On Sat, 18 Feb 2012 19:58:14 -0000, H. S. Teoh <hst...@quickfur.ath.cx> wrote:

On Sat, Feb 18, 2012 at 08:18:53PM +0100, Nathan M. Swan wrote:
On Saturday, 18 February 2012 at 18:52:05 UTC, 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.
[...]
Here's a compromise I would suggest: we have the different exception
types for different exceptional behaviors, but still they all
descend from a common exception type that has a field with the
module name; this way, the client can choose which way they want to
go.

I think deadalnix's approach is better. Exceptions should not be
categorized by module. What if the module depends on submodules? Then
catching only that module's exceptions will miss exceptions thrown from
submodules. No, exceptions need to be based on *semantics* rather than
modules, like CommandLineException, not GetOptException.

The way I currently prefer to use exceptions in C++ is to have 1 exception type per module. That module will catch and wrap *all* exceptions thrown by modules it calls. i.e.

[somemodule.cpp]
...
try
{
...
}
catch(OtherModuleException &ex)
{
  throw SomeModuleException("lalala", ex);
}

In this way I know, when calling a method in SomeModule, the only exception I need to catch is SomeModuleException.

So, code which uses multiple modules might look like..

try
{
SomeModule a = new..
OtherModule b = new ..
...
a->method();
...
b->method();
}
catch(SomeModuleException ex)
{
...
}
catch(OtherModuleException ex)
{
...
}

where typically one of those modules is something like a tcpip socket module, or a database module and the other may be something much more specific/different (which internally could use sockets etc).

In the case of more complex modules, where I want to allow different error cases to be caught separately I might define multiple exceptions, named on error semantics, but all prefixed with the module i.e. SomeModule<semantic_error>Exception - but again, the module methods/functions will always catch and wrap all exceptions from all modules it itself calls so you have a small finite list of exceptions you need to worry about.

Basically, I've taken exception handling and flattened it somewhat to make it easier to keep track of what exceptions can be thrown when/where and what I need to worry about handling. It is still possible to dig into an exception and get the inner/cause exception, and theoretically I could alter my behaviour based on that, but I've never needed to yet.

All my exceptions come from a common base, except for certain "errors" which are only caught at top level locations i.e. process main, thread main, or the top of a conceptual "task" or task engine. These are derived from a separate base type - much like we have Error and Exception in D - in fact, I probably got the idea from this NG :p

It would be nice if there was a mixin template that creates an
exception class that acts like this; making similar exception
classes is annoying.

+1 I use a macro in C++ for this.

Regan

--
Using Opera's revolutionary email client: http://www.opera.com/mail/

Reply via email to