The Right Approach to Exceptions

H. S. Teoh hsteoh at quickfur.ath.cx
Mon Feb 20 12:53:32 PST 2012


On Mon, Feb 20, 2012 at 05:31:28PM -0300, Juan Manuel Cabo wrote:
> > ...
> > Sure. Again, this is not advocating replacement of exception hierarchies with tables!
> > ... 
> > 
> > Andrei
> > 
> 
> I think that the case of rethrowing an exception with added detail is
> the worst enemy of clean Exception hierarchies.

Hmm. This is a valid point. Sometimes you want to add contextual details
to an exception in order to provide the final catching code with more
useful information. Otherwise you may end up with a chain of mostly
redundant exception classes:

	class UTFError : Exception {...}
	class LexUTFError : LexUTFError {
		int line, col;
		...
	}
	class ConfigFileParseError : LexUTFError {
		string cfgfile_name;
	}

	auto decodeUTF(...) {
		...
		throw new UTFError;
	}

	auto configLexer(...) {
		try {
			...
			decodeUTF(...);
		} catch(UTFError e) {
			throw new LexUTFError(...);
		}
	}

	auto configParser(...) {
		try {
			...
			configLexer(...);
		} catch(LexUTFError e) {
			throw new ConfigFileParseError(...);
		}
	}


> The idea of Variant[string] remedies that case without creating a new
> exception class just for the added fields. If that case is solved,
> then the tipical need for creating new exception types that don't
> really aid selecting them for catching and recovery is solved too.
[...]

However, I still hesitate about using Variant[string]. How would you
address the following problem:

	// Module A
	class MyException : Exception {
		this() {
			info["mydetail"] = ...;
		}
	}

	// Module B
	auto func() {
		try {
			...
		} catch(MyException e) {
			if (e.info["mydetail"] == ...) {
				...
			}
		}
	}

If module A's maintainer renames "mydetail" to "detail", then module B
will still compile with no problem, but now e.info["mydetail"] doesn't
exist and will cause a runtime error at worst. At best, the catch block
won't be able to recover from the error as it did before, because now it
can't find the info it was looking for.

If "mydetail" had been a field stored in MyException, then module B
would get a compile-time error, and the problem can be fixed
immediately, instead of going unnoticed until it blows up at the
customer's production server.


T

-- 
Some ideas are so stupid that only intellectuals could believe them. --
George Orwell


More information about the Digitalmars-d mailing list