[LispM-Hackers] Error handling

James A. Crippen james@UnLambda.COM
Sun, 8 Apr 2001 01:14:00 -0800 (AKDT)


I'm working out on paper a good method for handling errors after realizing
that my first attempt isn't going to be very scalable and isn't really in
the OO spirit.

Here's what I'm thinking...  This is the class hierarchy for errors.  
Instantiated objects are exceptions to be thrown.  Exceptions are passed
upwards until they are caught, perhaps at the top level.

class e3Error (noninstantiable)
 |
 +- class e3ErrorLuser (noninstantiable)
 |   |
 |   +- class e3ErrorAchtung (recoverable errors, warnings)
 |   |
 |   +- ... (various other luser errors)
 |  
 +- class e3ErrorEmulated (noninstantiable)
 |   |
 |   +- class e3ErrorUCode
 |   |
 |   +- class e3ErrorCrash
 |   |
 |   +- ... (various other errors that the emulated system may encounter)
 |
 +- class e3ErrorInternal (noninstantiable)
 |   |
 |   +- class e3ErrorFixme
 |   |
 |   +- class e3ErrorNotDone (unimplemented functionality error)
 |   |
 |   +- class e3ErrorCantHappen
 |   |
 |   +- ... (other errors internal to emulation system)
 |
 +- class e3ErrorFatal (noninstantiable)
     |
     +- class e3ErrorDebug ?
     |
     +- class e3ErrorDeath ?

The Fatal error will cause a nonrecoverable exit from the system.  The
other errors except for Luser errors are allowed to cause Fatal errors
under certain conditions.  Any Fatal error is required to produce some
form of diagnostic information, debugging information, or backtrace (or
all of the above).  Fatal errors can also cause core dumps if they're
required.  Some Fatal errors may drop into a debugger (the FEP) instead of
exiting the whole system, but this is debatable.

Luser errors are for when the user has made some stupid mistake, like
specifying a load band that doesn't exist, not providing a valid file for
using as a disk, etc.  Achtung errors are warnings to the luser that
they've made a stupid mistake or forgotten to specify something but the
system is continuing with default values.  Other errors are to be
specified.

Emulated errors are those that should be emualated (duh!).  These errors
are ones that can happen in the microcode (UCode errors), crashes,
etc.

Internal errors are those which indicate some sort of abnormal state of
the emulation system.  These include Fixme errors where the functionality
in question needs work, NotDone errors which are placeholders for
functionality which is nonimplemented, and CantHappen errors are
naturally errors that shouldn't happen and indicate that some sort of
programmer error or logic failure has occurred.  CantHappen errors are
probably going to cause Fatal errors in every case, and might be moved to
the Fatal class.

Please give me comments.  You other people have probably implemented more
error handling systems than I have, since most of mine in the past have
been ad hoc.

'james

-- 
James A. Crippen <james@unlambda.com> ,-./-.  Anchorage, Alaska,
Lambda Unlimited: Recursion 'R' Us   |  |/  | USA, 61.2069 N, 149.766 W,
Y = \f.(\x.f(xx)) (\x.f(xx))         |  |\  | Earth, Sol System,
Y(F) = F(Y(F))                        \_,-_/  Milky Way.