If it's a large project, I tend to have a base exception class that derives from System.Exception
for all domain-specific exceptions. So if the product name is "Foo" then all exceptions derive from "FooException".
I'm not calling this a best practice, and I wouldn't be surprised if some people insist that it is a bad practice, but it has a few advantages in my book:
- If you ever want to merge projects or write hybrid applications, having that class at the root of the hierarchy clearly tells you which subsystem has a rule or assumption that got violated. Makes it much easier to investigate a bug report in some big orchestration.
- It's a completely unambiguous standard to have, and developers never have to worry about things like whether to inherit from
Exception
or DbException
.
- It makes it easier to add project-global information to the exception tree if you ever have to (for example, a web app/service might want to include information about the current security context, or the server node that the exception occurred on). Not that you'll always need or want this, but there are instances when you might.
If you have several large sub-projects (say Foo.Core
for the domain model, Foo.Data
for the data layer, Foo.Services
for the business logic, and Foo.UI
for the view model), then I might also create a root exception for each one, derived from FooException
. In this particular case it would be FooDataException
, and every exception happening in the DAL (such as DuplicateEntryException
) derives from that. You would also have your FooServiceException
and FooUIException
and whatever else.
It's just opinion, though. I don't think there's any right or wrong answer.
Edit: Except for ApplicationException
, which is the wrong answer!