views:

74

answers:

2

Hey guys,

It dawned on me that I've never seen a single exception hierarchy for which creating subclasses but catching the parent class was actually useful (except, of course, for the base Exception class, that has to be derived).

Are exception hierarchies really useful, xor should all exceptions be derived from language's base exception class?

+5  A: 

Exception hierarchies are useful for grouping related exceptions together, when you need different granularity of catching in different places.

Putting all application exceptions in one place is the commonest use case. This allows you to catch MyAppException any time that you want to trap all errors coming from your application, but still catch more specific exceptions when appropriate. (In .NET, the ApplicationException class was meant for this, but it's been deprecated for various reasons.)

But you can also group exceptions together at module boundaries, or in any other way that makes sense. Use FooModuleException for exceptions coming from the Foo module, but catch and handle FooModuleMustFrobnicate specially internal to Foo. Or any equivalent situation.

I've used all of these patterns at different times.

JSBangs
Do you have an example where catching exceptions at a different granularity is actually useful? I mean, if we forget all theory and get practical, I've never seen a place where granularity of catches was actually used. On the other hand I've seen lots of people catch `IOException` when they open a file, and yet all they can get is a `FileNotFoundException`. They use `IOException` because the hierarchy makes them think something else related might happen while in fact, `IOException` subclasses are pretty disjointed in terms of contexts of appearance.
zneak
+1  A: 

I've never created a single exception hierarchy for whole application, because an exception in general can bring different semantic and, therefore, needs to handled differently.

Some exceptions inform about system faults, another exceptions inform about bugs, and some other - about some exceptional condition, that could be gracefully recovered on higher level.

For this "business-logic" exceptions exception hierarchy can help you not to violate open-closed principle during overriding some methods in descendants.

Consider following example:

public abstract class Base
{
   /// Perform some business-logic operation
   /// and throw BaseFooException in certain circumstances
   public abstract void Foo();
}

public class Derived1 : Base
{
   /// Perform some business-logic operation
   /// and throw DerivedFooException in certain circumstances.
   /// But caller could catch only BaseFooException
   public abstract void Foo() {}
}

class BaseFooException : Exception {}

class DerivedFooException : BaseFooException {}

Exception hierarchy may be helpful in custom framework or in specific libraries, but in general case (in business applications) I don't think that creating one deep and wide exception hierarchy is a good idea.

Sergey Teplyakov