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