The Right Approach to Exceptions

Sean Cavanaugh WorksOnMyMachine at
Sat Feb 18 19:45:52 PST 2012

On 2/18/2012 7:56 PM, Zach wrote:
> On Sunday, 19 February 2012 at 01:29:40 UTC, Nick Sabalausky wrote:
>> Another one for the file of "Crazy shit Andrei says" ;)
>> From experience, I (and clearly many others here) find a sparse, flat
>> exception hierarchy to be problematic and limiting. But even with a
>> rich detailed exception hierarchy, those (ie, Andrei) who want to
>> limit themselves to catching course-grained exceptions can do so,
>> thanks to the nature of subtyping. So why are we even discussing this?
> How about we revisit ancient design decisions which once held true...
> but no longer is the case due to our "god-language" being more expressive?
> In my experience an "exception hierarchy" is never good enough, it
> suffers from the same problems as most frameworks also do... they
> simplify/destroy too much info of from the original error.
> ex why don't we throw a closure? Of course we could go crazy with mixins
> and CTFE,CTTI,RTTI aswell... imho the goal should not be to do as good
> as java, the goal is progress! Java should copy our design if
> anything... we could have a very rich exception structure... without the
> need for a hierarchy.
> try(name) // try extended to support full closure syntax
> {
> DIR* dir = opendir(toStringz(name));
> if(dir==0 && errno==ENOTDIR)
> throw; // throws the entire try block as a closure
> }

My C++ experience revolves around some rather large codebases that do 
not have exceptions enabled at all.  The more I look into seeing what it 
would take to start using them, all I see are some pretty huge downsides:

The exact nature of the error for a lot of exceptions for like File I/O 
are very platform specific.  Throwing these objects effectively bubbles 
up highly platform specific data up to the caller, which infects the 
caller with the need to deal with platform specific data (posix codes vs 
GetLastError, vs various return values from the functions that failed 
etc).  This is not a good thing for keeping a codebase isolated from 
platform differences.

There has been seeing a huge shift in needing to make everything I work 
on threaded on a fine-grained level (game simulation, graphics 
rendering, various physics based systems and simulations, networking 
etc).  The way exceptions work, unwind the stack until someone 'cares', 
is not a good model in this environment.  Ideally everything is on its 
own thread or exists as a job in a job queue, or exists as some kind of 
node in a flow based system.  In these environments there is no caller 
on the _stack_ to unwind to.  You have to package up another async 
message with the failure and handle it somewhere else.  In many ways 
this is superior, as it solves the problem exceptions were created to 
solve : route errors to the proper code that 'cares'.

In the Von Neumann model this has been made difficult by the stack 
itself.  Thinking of exceptions as they are currently implemented in 
Java, C++, D, etc is automatically artificially constraining how they 
need to work.  Exceptions as they are now exist as a way to jump up the 
stack some arbitrary amount (until a handler is found).  The real 
problem that needs solving is 'route errors the most appropriate place 
available' with the constraint of 'keep the program in a working state'. 
  I would prefer a system that works equally well in both kinds of 
environments, as we are already mixing the styles, and switching code 
from one to the other requires a large amount of refactoring due to the 
differences in error handling.

More information about the Digitalmars-d mailing list