views:

33

answers:

2

I want to add DataAccessLayerException and DuplicateEntryException classes. But I'm in big doubts of which classes should I derive from? For example DataAccessLayerException (will be used as a wrapper for exceptions thrown from data access layer) may be derived from Exception or DbException. But I'm afraid that DbException should be the base class only for provider exceptions like OracleException or SqliteException and so on. I don't know. And DuplicateEntryException (yes, I hate that this exception is not implemented by db providers, so I will create it myself) can be derived from Exception or DbException or even from DataAccessLayerException.

What do you think? Also please give arguments why you think so.

Please, experienced developers/architects only.

Thank you in advance.

+1  A: 

I think I would base custom exceptions on the Exception class. I'm assuming that you are planning to wrap any exception that would be a DbException that is thrown by the code you are using. If so, then using Exception makes it plainer that the calling code should not catch the base class exception rather than your custom exception. This is because it's generally bad practice to catch a generic Exception. Basing on DbException would allow the user of your code catch a DbException and mistakenly catch unwrapped exceptions since both your exceptions and the unwrapped ones are based on the same class.

If you aren't wrapping all exceptions, then I might reconsider and make your exceptions specializations of DbException. This would be the case where you want the user to actually be able to catch DbExceptions, including yours, or be able to handle your exceptions differently. Sorry for the waffle, but I think it really does depend on your goals. For what it's worth, I generally go with the former way and base custom exceptions on the lowest base class.

P.S. I have no idea whether I qualify as an experienced developer/architect, but I do have opinions.

tvanfosson
+1  A: 

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!

Aaronaught