[LispM-Hackers] Error system

James A. Crippen james@UnLambda.COM
Tue, 10 Apr 2001 10:50:50 -0800 (AKDT)


My latest idea for the error system was influenced by a friend who
mentioned Java's 'Throwable' hierarchy and that C++ has essentially a
similar mechanism without the hierarchy.  So here's my idea.

class e3Throwable
 |
 +- class e3Error
 |   |
 |   +- class e3ErrorLuser
 |   |   |
 |   |   +- class e3ErrorWarning
 |   |   |
 |   |   +- ... (other luser errors?)
 |   |
 |   +- class e3ErrorEmulated
 |   |   |
 |   |   +- class e3ErrorUCode
 |   |   |   |
 |   |   |   +- ... (different ucode errors)
 |   |   |
 |   |   +- class e3ErrorCrash
 |   |   |
 |   |   +- ...
 |   |
 |   +- class e3ErrorInternal
 |       |
 |       +- class e3ErrorFixme
 |       |
 |       +- class e3ErrorDebug
 |       |
 |       +- class e3ErrorNotDone
 |       |
 |       +- class e3ErrorFatal
 |       |
 |       +- class e3ErrorCantHappen
 |
 +- class e3Exception

Now we have Throwable which is anything that can be used with the 'throw'
keyword.  This is divided into Errors and Exceptions.  I don't have a use
for Exceptions, but maybe someone will need them (to avoid using longjmp()
for instance).

Errors are further divided into three major categories.  The Luser errors
are what happen to users, and are due to input or configuration
errors.  They are usually continuable.

Emulated errors are those which are mentioned in the SSDN2 and the
like.  Misuse of a macroop should cause a UCode error, for instance.
A Crash would necessarily result from a system crash.  The handler for a
Crash would be required to do all the cleanup necessary and try to write a
crash record.

Internal errors are those which are caused by bad programming.  Fixme
errors are functionality that is broken.  NotDone errors are functionality
that is nonexistent.  Fill in all the unfinished macroops with NotDone
throws.  Debug errors are those that should drop into a debugger of some
sort because something in the system is anomalous, but possibly
recoverable with assistance, and would be of interest to the
programmer.  Fatal errors obviously end with calling exit() after some
cleanup or the like, and they should try to write diagnostic information
or a crash record or similar.  CantHappen errors are for code that should
never be reached under normal operating conditions.

These are naturally extensible.  The classes will not be much more than
placeholders which implement some error notification functionality, or in
some cases diagnostic and crash record writing.  The handlers are expected
to call the appropriate functions implemented in the error classes to
write notifications and perform other error handling operations.  The
error classes themselves are not meant to handle cleanup except in a
generalized way (such as Fatal calling the ~e3Lispm destructor, perhaps).

These classes are extensible.  If someone needs to implement a local error
handling mechanism then they should extend the e3Error class or one of the
appropriate subclasses.  If this results in a whole new hierarchy being
built then the implementor should consider folding some of the
functionality back into the main error system.

The Exception class is really a placeholder.  It's just meant to allow
extension in a different direction from error handling.  It may or may not
remain.

'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.