The Right Approach to Exceptions

H. S. Teoh hsteoh at quickfur.ath.cx
Sat Feb 18 11:41:55 PST 2012


On Sat, Feb 18, 2012 at 12:52:05PM -0600, Andrei Alexandrescu wrote:
> There's a discussion that started in a pull request:
> 
> https://github.com/alexrp/phobos/commit/4b87dcf39efeb4ddafe8fe99a0ef9a529c0dcaca
> 
> 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.

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.

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?
	}

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. 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.


T

-- 
Try to keep an open mind, but not so open your brain falls out. -- theboz


More information about the Digitalmars-d mailing list