The Right Approach to Exceptions

Andrei Alexandrescu SeeWebsiteForEmail at
Sat Feb 18 15:47:58 PST 2012

On 2/18/12 1:41 PM, H. S. Teoh wrote:
> On Sat, Feb 18, 2012 at 12:52:05PM -0600, Andrei Alexandrescu wrote:
>> There's a discussion that started in a pull request:
>> Let's come up with a good doctrine for exception defining and handling
>> in Phobos. From experience I humbly submit that catching by type is
>> most of the time useless.
> [...]
> It's only useless because of a poorly-designed exception hierarchy.
> Java, for example, has useful things like FileNotFoundException,
> DiskFullException, etc., that you can catch to handle specific problems
> in a specific way. They are also part of a well-designed hierarchy. For
> example, both of the above exceptions are subsumed under IOException, so
> if you wanted to handle a general I/O exception and don't care which one
> it is, you could just catch IOException.

It's great that you bring expertise from the Java world. I should note 
that the above does little in the way of putting an argument to the 
table. It appeals to subjective qualifications ("poorly designed", "well 
designed") so one's only recourse to getting convinced is just believing 
what you say without any evidence. It's equally unimpressive that 
FileNotFoundException and DiskFullException inherit IOException; seeing 
that one might say "yeah, sure" but there should be some compelling 
evidence that the distinction makes a difference.

> Now, granted, there are limitations to such a design, for example if you
> want to catch a category of exceptions that don't map precisely to a
> node in the inheritance hierarchy. It may be possible to deal with such
> situations by making Exception an interface instead, although that may
> introduce other issues.

 From this and other posts I'd say we need to design the base exception 
classes better, for example by defining an overridable property 
isTransient that tells caller code whether retrying might help.

> Either that, or allow a list of exceptions in a catch() block, but that
> would require some further thought, because blindly allowing multiple
> arguments to catch introduces an initialization problem:
> 	try { ... }
> 	catch(FileNotFoundException e1, DiskFullException e2) {
> 		// which of e1, e2 is actually thrown?
> 	}

It seems exceptions still are not entirely understood, and I agree that 
adding some random mechanism doesn't do good.

> The problem with this approach is the proliferation of of exception
> classes, many of which differ only in fine ways that most applications
> wouldn't even care about. The basic problem here is that we are mapping
> what amounts to error codes to classes.

Yes. Types, to be more general. The question is why are various error 
deserving of their own types.

> C++ does allow throwing
> arbitrary objects (IIRC), so in a sense you *could* throw an error code
> instead of a class object. But that's not necessarily a good thing,
> because then you end up with different modules throwing different,
> mutually incompatible enumerated error codes, which brings us back to
> square two (not square one because at least we don't have to manually
> propagate error codes in every level of the call stack), where we have a
> bunch of incompatible error types and we don't necessarily know what to
> do with them. Having a common root to all exceptions is a good thing.

I didn't contend the opposite.


More information about the Digitalmars-d mailing list