The Right Approach to Exceptions

Juan Manuel Cabo juanmanuel.cabo at gmail.com
Mon Feb 20 11:10:28 PST 2012


On 02/20/2012 02:57 PM, Andrei Alexandrescu wrote:
> 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