Exception programming difficult

Marco Leise Marco.Leise at gmx.de
Mon Aug 13 11:39:47 PDT 2012


Am Mon, 13 Aug 2012 19:54:47 +0400
schrieb Dmitry Olshansky <dmitry.olsh at gmail.com>:

> On 13-Aug-12 19:50, Timon Gehr wrote:
> > On 08/13/2012 05:32 PM, Dmitry Olshansky wrote:
> >>
> >> I think the true cryptonite that melts "checked exceptions" to a pile of
> >> green goo is templated code:
> >>
> >> So (*yawn*) tell what kind of exception specification the following
> >> function should have:
> >>
> >> auto joiner(RoR, Separator)(RoR r, Separator sep);
> >>
> >> How would you guarantee upfront what kind of exceptions it can throw is
> >> beyond me. It all depends on code that you can't reach or know by the
> >> very definition of template.

The good thing is whatever your argument is, nothrow inevitably has to suffer from it, too.
Really I'd like to label this situation as 'bad', when you don't know what exceptions a function may throw. Then why have different exception types at all?

> > Well, presumably the exception specification would be inferred
> > automatically for templates.
> 
> What's the propose then? And how end user will get any idea what to put 
> in his function where he uses it? I see one, but it's not pretty - run 
> compiler once - see complaints, add requested types to throws, re-run 
> the compiler?

Yes it is that bad(tm) ^^. Ok, who is the end user? If I am the user of someone's library and it has an @throws(...) spec, I get an exact idea what to put into my code to handle the exceptions - if I want to.

If I'm writing library code on the other hand it depends on the business I'm doing. I'd expect that fast living close to the market code will likely not use this feature, whereas libraries want to be specific about their public API, which includes the exceptions that they throw. I see it as a final step alongside the documentation of a library to add the @throws(...), so it doesn't break the workflow much.

As for the benefits:

o can act as a contract in class hierarchies when used on overrideable methods
o allows you to decide at any point to limit the thrown exceptions to a certain set
  (e.g. handle cases of ConvException or UTFException before the public API)
o makes this automatically visible in DDoc (including any comment on the exception)
  @throws(ReadException /** if it is not correct. */);
o you don't have to document them manually and keep the DDoc up to date,
  which is much more time consuming than running the compiler twice
o let the compiler work for you
o I am a lousy salesman writing walls of text


Take a look for example at the socket API. Some methods specify the thrown exceptions, others only hint at them by catching them in examples or don't document them at all. You have to start guessing or digging through the source code to find out which error situations result in what exceptions. The InternetAddress ctor taking a host name looks innocent for example as well as most of the Socket methods.

In std.datetime, there is a function TimeZone.getInstalledTZNames() where I wonder if the docs are correct. They say on Windows it throws a DateTimeException when the registry cannot be read, but around the actual registry function call I see no try catch to wrap the thrown exception.

std.format is sometimes throwing FormatException, but sometimes Exception on similar cases or an UTFException.

-- 
Marco



More information about the Digitalmars-d mailing list