The Right Approach to Exceptions

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Sat Feb 18 23:05:25 PST 2012


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


More information about the Digitalmars-d mailing list