On 2/20/12 1:38 AM, Jonathan M Davis wrote:
On Monday, February 20, 2012 01:10:39 Andrei Alexandrescu wrote:
ModuleException and PackageException have one important thing going for
them: they automate away a good amount of boilerplate, which makes them
interesting for me to look at, and worth sharing as long as we're
brainstorming. The associated issues as clear as the advantages.
Probably ModuleException is too specific to be interesting, but
PackageException seems useful.

It saves no boilerplate at the catch point, because you have to know what
you're catching to do anything useful with it. It could be that you choose to
catch a common exception rather than a specific one (e.g. IOException instead
of FileException), but regardless of whether you use templates or mixins or
whatever to generate the exception type's source code, you still need to write
the handling code by hand. Handling code is _not_ the sort of thing that can
be automated.

Absolutely. For catching we're looking for allowing centralization, not for automation.

And as for saving boilerplate in defining exceptions, well some of that could
be done via mixins, but since useful exceptions often have additional member
variables, you're going to have to write many of them by hand anyway.

Again, I think this thread clarified we need the "Variant[string] info;" member however we define the hierarchy.

Also, I think we can do better than defining the boilerplate constructor (see e.g. https://github.com/D-Programming-Language/phobos/pull/439). It's just a function. Consider:

// this goes in the stdlib
void raise(ConcreteException)(string message, Throwable t = null, string f = __FILE__, size_t l = __LINE__)
{
  auto r = new ConcreteException;
  r.message = message;
  r.file = f;
  r.line = l;
  r.next = t;
  throw r;
}

class AcmeException : Exception {}

Now whenever you want to raise AcmeException, you say raise!AcmeException("message"). Also, raise may accept additional data that fills the Variant[string]. That makes exception definitions one-liners.

And as has been said before, ultimately the module that an exception comes
from doesn't mean much. It's what went wrong that matters. And ideally, the
standard library would have exception types that user code would throw or
derive its own exception types from, in which case the exception types get
even more divorced from the modules that they're declared in. So, ultimately,
tying exceptions to modules or packages is _not_ a good idea in the general
case. Sometimes it makes sense - particularly if you're talking about making a
base exception type which a project as a whole uses (e.g. a PostgresException
for a postgres library) - but in general, it's a bad approach, and it's one
that we should be moving away from.

I tend to agree, particularly because it's easier for people to remember express names instead of origins encoded by module. Ironically, many of Phobos' exceptions today follow the exception-to-module correspondence. Still I think it's worth keeping in mind the possibility of having the PackageException as a base trail for various exceptions specific to a package.


Andrei

Reply via email to