The Right Approach to Exceptions

Juan Manuel Cabo juanmanuel.cabo at
Sun Feb 19 05:53:09 PST 2012

I uploaded my little 2003 article on exception categorization to 
where I detailed my whole point_of_view_of_the_catch and 
whole_program_invariant phylosophy for organizing clasess, and 
C++, .NET and Java hierarchies. Its not a professional article, 
and I never wrote a translation to english:


On Sunday, 19 February 2012 at 10:30:45 UTC, Juan Manuel Cabo 
> Hello D community! This is my first post!! I hope I can bring 
> clarity to all this. If not, I apologize.
> Some time ago I researched the best way to classify exceptions 
> and build a hierarchy. I came up with the following rules:
> 1) At the top level, there would be RecoverableExceptions and 
> FatalExceptions (or you can call them something like 
> CatcheableException and FatalExceptions, or Exception and 
> Error).
> 2) Fatal exceptions shouldn't be catched. They imply that the 
> program lost basic guarantees to go on (memory corruption, 
> missing essential file, etc.). You could catch them if you 
> wanted to, but it makes no sense other than at your top-level 
> method (main(), etc.).
> 3) A RecoverableException can be converted to a FatalException 
> by rethrowing it, once a catch decides so. You shouldn't do the 
> reverse: a FatalException never should be converted to a 
> RecoverableException.
> 4) It makes no sense to subclass FatalExceptions since there 
> won't be a catch that groups them in a base type (since they 
> are not catcheable).
> 5) Only create a new RecoverableException class type if it 
> makes sense to write a catch for it alone. Otherwise, use an 
> preexisting type.
> 6) Only group RecoverableExceptions in a category if it makes 
> sense to write a catch for that category. Please don't group 
> them because its fancy or "cleaner", that is a bad reason.
> Who decides when an Exception is Unrecoverable? Library code 
> almost never decides it, since an exception is only 
> unrecoverable if the whole_program_invariant got broken, and 
> libraries are only a part of a program. So they will tend to 
> throw RecoverableExceptions, which can be reconverted to 
> Unrecoverable by the program.
> In some cases, it is clear that an exception is Unrecoverable. 
> When you call a function without satisfying its arguments 
> precondition (ie: null argument) the only way to fix that is by 
> editing the program. You shouldn't have called it like that in 
> the first place, why would you? So you let the 
> UnrecoverableException bubble up to your main function, and log 
> its stacktrace to fix it.
> Unrecoverable means the program got 'tainted', basic guarantees 
> got broken (possible memory corruption, etc.). Most exceptions 
> will be Recoverable.
> Now, expanding on the hierarchy: I said that it makes no sense 
> to subclass UnrecoverableExceptions. Recoverable exceptions on 
> the other hand, need to be subclassed 
> _with_the_catch_on_your_mind_. You are passing info from the 
> throw site to the catch site. The catch block is the 
> interpreter of the info, the observer. You are communicating 
> something to the catch block.
> So please, do not create a new types if there is no value in 
> writing a catch that only cathes that exception and that can 
> recover from that exception. Otherwise, use an existing type.
> I wrote these rules some time ago. Please excuse me if they 
> come off a bit pedantic!!!!!!!!!!!! Its all only a clarifying 
> convention.
> According to all this:
> * FileNotFoundException is useful. It tells you what happened. 
> It is a RecoverableException (under my convention) because 
> until it reaches the program, the library doesn't know if the 
> program can recover from that (it could be a system missing 
> file, or just a document the user asked for).
> * DiskFailureException is only useful if someone can write a 
> catch for it. If so, then it is a RecoverableException. Only 
> the program can decide if it broke basic guarantees.
> * Most argument exceptions are Unrecoverable. A function 
> throwing shouldn't have been called like that in the first 
> place. The only fix is to go back to editing the program. 
> (precondition broken).
> Another thing: you cannot decide whether an exception is 
> Unrecoverable based only on whether the thing that got broken 
> is the postcondition of a function. It is the 
> whole_program_invariant that decides that. For instance:  
> findStuff(someStuff)  might not know if someStuff is important 
> enough for the stability of the program if not found. The 
> postcondition is broken if it doesn't return the Stuff. That 
> might be recoverable.
> And PLEASE: don't make classifications by the point of view of 
> the cause of the problem. DO make classifications by the point 
> of view of the fixing/recovery of the problem; the catch block 
> is who you are talking to. 
> FileNotFoundBecauseFilesystemUnmounted is worthless.
> So, to sum up: (1) it makes no sense to subclass fatal 
> exceptions, and (2) never subclass a RecoverableException if 
> you are not helping a catch block with that (but please do if 
> it aids recovery).
> verbose and pedantic for my first post... yikes.. i beg 
> forgiveness!!!
> On Sunday, 19 February 2012 at 09:27:48 UTC, Jonathan M Davis 
> wrote:
>> On Sunday, February 19, 2012 19:00:20 Daniel Murphy wrote:
>>> I wasn't really serious about implicit fallthrough.
>> Lately, it seems like I can never tell whether anyone's being 
>> serious or not online. :)
>>> Out of the syntaxes I could come up with:
>>> catch(Ex1, Ex2 e)
>>> catch(e : Ex1, Ex2)
>>> catch(Ex1 | Ex2 e) // java 7 syntax, horrible
>>> I like (e : list) the best.  Naturally it would also accept a 
>>> type tuple of
>>> exceptions.
>> LOL. Personally, I actually think that the Java 7 syntax looks 
>> great (I'd never seen it before), but catch(e : Ex1, Ex2) is 
>> just as good and more consistent with the language as a whole, 
>> since it doesn't try to give any operators a new meaning (as 
>> Java's does).
>> - Jonathan M Davis

More information about the Digitalmars-d mailing list