The Right Approach to Exceptions
Jonathan M Davis
jmdavisProg at gmx.com
Mon Feb 20 10:52:15 PST 2012
On Monday, February 20, 2012 12:28:27 Andrei Alexandrescu wrote:
> On 2/20/12 12:20 PM, Jonathan M Davis wrote:
> > On Monday, February 20, 2012 18:05:38 foobar wrote:
> >> Separation of concerns - exceptions are meant to notify the
> >> *developer* of errors. User facing error messages is a separate
> >> concern that exceptions should not be responsible for. it's not
> >> just outsourcing the translation strings, it's the developer's
> >> job to determine what if at all should be done with the exception.
> >
> > Agreed. Users shouldn't be seeing exception messages. They are intended
> > for
> > the developer. Users don't know or care about them. You don't display
> > error
> > codes to users when something goes wrong do you?
>
> You don't want to duplicate all over the place formatting code do you?
Most of the time that won't happen simply because you need different formatting
code for different types of errors and contexts. And if it does, you can just
write a function which takes the exception and prints out the message that you
want with the formatting that you want.
Also, for contexts where you're going to give a message to the user, toString
doesn't cut it, because it's doing stuff like putting the stack trace in the
message. So, do you intend to effectively have _two_ error messages with every
exception - one for the developer and one for the user?
So, in the cases where you need to save on formatting code, I don't think that
it's hard to do so without adding anything to Exception, and it's stuff which
frequently needs to be application-specific anyway, in which case, Exception
couldn't possibly provide the right message anyway.
> > And adding an
> > internationalization mechanism would actually make things _worse_, because
> > it complicates exceptions for something that they don't generally need,
> > and it makes debugging harder, because you can't see the message as
> > easily in the debugger.
> >
> > The fields and functions that exceptions have should be geared towards
> > facilitating the program processing and recovering from the exception, not
> > printing out error messages. And a big part of that is giving them fields
> > which can be processed programmatically, not ways to print
> > internationalized strings.
>
> Yes. Programmatic processing in a class hierarchy means you want to push
> policy up and implementation down. If you don't do this, you need to
> duplicate client code to work with each derived class, instead of having
> client code deal with good primitives.
So, instead of
catch(SpecificException1 e)
{
//use fields specific to this exception to do whatever you need to do
}
catch(SpecificException2 e)
{
//use fields specific to this exception to do whatever you need to do
}
catch(GenericException e)
{
//handle the generic exception as best you can given the lack of
//a specific one
}
you end up with something effectively along the lines of
catch(GenericException e)
{
if(/* e is SpecificException1 */)
{
//use fields specific to this exception to do whatever you need to do
}
else if(/* e is SpecificException2 */)
{
//use fields specific to this exception to do whatever you need to do
}
else
{
//handle the generic exception as best you can given the lack of
//a specific one
}
}
How is that better? It's throwing away catch's ability to put the program
execution in the correct handling code. I don't see how your suggestion is an
improvement over using an actual class hierarchy. You can't generally make the
handling uniform unless the catch block is simply going to do something like
log the message rather than handle it. And if you're doing that, you can just
catch the more generic exception.
It seems like you want to effectively do something like add a method to
Exception along the lines of handleException which exception handling code
calls so that it's nice and generic. But it's the exception handling code
which needs to do specific stuff and thus frequently _can't_ be generic.
Also, how would the whole variant hash work with purity? You can access global
variables in pure functions. So, I wouldn't expect it to work in a pure
function. Class hierarchies do. I would think that that would kill the whole
idea right there, even if it were better than using a class hierarchy (which I
don't think that it is).
- Jonathan M Davis
More information about the Digitalmars-d
mailing list