On 2/18/12 8:45 PM, Jonathan M Davis wrote:
On Saturday, February 18, 2012 20:28:32 Andrei Alexandrescu wrote:
On 2/18/12 6:36 PM, H. S. Teoh wrote:
Note also, that an elaborated exception hierarchy lets you attach
additional specific information that might be useful in error recovery.
For example, FileException may have a field containing the filename that
caused the error, so that if the program is processing a list of
filenames, it knows which one went wrong. You would not want such
information in Exception, because it only applies to FileException's.

If an exception adds state and/or interface to the table, I agree that
may justify its existence as a distinct type.

If all you're arguing is that something like StringException shouldn't exist
because it doesn't add any additional member fields, then that's a much more
reasonable thing to debate. I'm not quite sure I agree, but some of your
responses seem to indicate that you don't want a rich exception hierarchy.

Ideally we'd have the right number of types - not more, not less. The main purpose of this thread is to figure how many exception types are "just right". There has been a tendency in Phobos to just add a module-specific exception to certain modules, without a good reason. I'm trying to figure out the reasons.

In the case of getopt, at _least_ adding a GetOptException with a field for the
failed flag would be very valuable, and having additional derived types which
indicate _why_ it failed would also be valuable.

The additional state sounds fine, but I'm not so sure about adding one type per failure reason.

And in some cases at least,
that would lead to more member fields in the derived exceptions (like the value
of the flag if it were given a bad value).

And aside from that? The universe of possible errors in getopt is finite, closed, and actually fairly small. Can't we do with fewer types?

I would argue however that there _are_ times when having a derived exception
which has no additional data beyond its type rather than simply Exception can
be useful - _especially_ when it's at the base of a larger hierarchy. For
instance, if we had an IOException, you could know that whatever operation you
were trying to do went badly because of an IO problem. You would probably need
to handle it as a subclass of IOException to get any particularly useful
information on how to handle the problem, but just knowing that it was an I/O
problem could be enough in some cases.

How about a system in which you can say whether an exception is I/O related, network related, recoverable or not, should be displayed to the user or not, etc. Such is difficult to represent with inheritance alone.

I really think that whether adding an exception type which adds no additional
member fields is a good idea should be evaluated on a case-by-case basis. We
don't want to needlessly create a bunch of useless, uninformative exception
types, but be we also want a rich enough exception hierarchy that it's
possible to intelligently recover from exceptions.

I think right now we're erring a bit on the side of defining useless and uninformative exception types. As far as the originating module goes, it makes perfect sense to make that a field in the base class.

Anyway, a simple action items right now is improve Exception's offering with things like e.g. custom formatting for i18n, more origin information, cloning, attributes and capabilities (transitory, user-visible etc).


Andrei

Reply via email to