The Right Approach to Exceptions
Andrei Alexandrescu
SeeWebsiteForEmail at erdani.org
Mon Feb 20 09:57:07 PST 2012
On 2/20/12 11:44 AM, foobar wrote:
> This extra processing is orthogonal to the exception. the same exception
> can be logged to a file, processed (per above example) and generate
> graphical notification to the user, etc. The exception contains the
> information pertaining only to what went wrong. the rest is not part of
> this discussion.
Exactly. I don't see how a disagreement follows from here. So isn't it
reasonable to design the exception such that it can offer information
pertaining to what went wrong, in a uniform manner?
> The exact same exception in the example would also be thrown on a
> mistyped URL in an application that tries to scrape some info from a
> website for further processing. The error is still the same - the url is
> incorrect but different use cases handle it differently. In the former
> example I might call to a i18n lib (someone already mentioned gettext)
> while in the latter I'll call a logging library with the the mistyped
> url (for statistics' sake).
> in the first I use the url to find a closest match, in the second I want
> to log said requested url. Both handled by *other* mechanisms.
> in both cases the exception needs a url field and in both cases I have
> no need for the Variant[string] map.
The Variant[string] map saves a lot of duplication whenever you want to
format a human-readable string (which is a common activity with
exceptions). It transforms this (I'm too lazy to write code anew by
hand, so I'll paste Jonathan's):
try
getopt(args, ...)
catch(MissingArgumentException mae)
{
stderr.writefln("%s is missing an argument", mae.flag);
return -1;
}
catch(InvalidArgumentException iae)
{
stderr.writelfln("%s is not a valid argument for %s. You must give
it a
%s.", mae.arg, mae.flag, mae.expectedType);
return -1;
}
catch(UnknownFlagException ufe)
{
stderr.writefln("%s is not a known flag.", ufe.ufe);
return -1;
}
catch(GetOptException goe)
{
stderr.writefln("There was an error with %s", goe.flag);
return -1;
}
//A delegate that you passed to getopt threw an exception.
catch(YourException ye)
{
//...
}
catch(Exception e)
{
stderr.writeln("An unexpected error occured.");
return -1;
}
into this:
try
getopt(args, ...)
catch(Exception e)
{
stderr.writeln(stringTemplate(typeid(e).toString(), e.info));
return -1;
}
The stringTemplate function loads the formatting template from a table
indexed on typeid(e).toString() and formats it with the info. It's
simple factorization.
Andrei
More information about the Digitalmars-d
mailing list