Xref: utzoo comp.software-eng:4402 comp.lang.c:33411 Path: utzoo!utgpu!news-server.csri.toronto.edu!clyde.concordia.ca!uunet!hsi!stpstn!cox From: cox@stpstn.UUCP (Brad Cox) Newsgroups: comp.software-eng,comp.lang.c Subject: Re: error handling techniques? Message-ID: <5765@stpstn.UUCP> Date: 3 Nov 90 16:33:24 GMT References: <1990Nov2.205831.23696@elroy.jpl.nasa.gov> Reply-To: cox@stpstn.UUCP (Brad Cox) Organization: Stepstone Lines: 48 In article <1990Nov2.205831.23696@elroy.jpl.nasa.gov> alan@cogswell.Jpl.Nasa.Gov (Alan S. Mazer) writes: >I'm interested in what approaches people use for error handling, particularly >in general purpose function libraries and large software systems. If someone >can reference a text or article, that would be good. > You can (and should) do a lot better than this even in languages (like Objective-C or C++) that don't (yet) support exception handling. The same tricks should be even easier in Smalltalk, but I'll leave this to Smalltalk people to verify. In what follows, I'm speaking of my own private research system, not the commercial Objective-C release, which I'm trying to get changed to adopt this scheme. The essence of the idea is to forbid routines that encounter exceptions from signaling the exception by returning normally with an abnormal return value. The idea is the following rule: if a message returns at all, the message has succeeded at its task and any values returned are valid, useful, and need not be checked. If it failed because of an exception, it *never* returns normally, but instead returns to a handler specifically for that exception. To adopt this scheme, seek out all old code that does this (such as Object factory methods like new and instance methods like doesNotUnderstand:, and utility stuff like assert()), recode them to invoke a generalized exception handling facility, perhaps by calling raiseException(anExceptionCode) or (as in my case) [AssertionException raiseException], [OutOfMemoryException raiseException], etc, etc. These calls access a stack of exception handlers, initialized at startup time with handlers that treat all exceptions in some usefully generic way, perhaps by printing the exception name and raising an inspector. This is a stack is so that your code can override the generic inspector with something more application specific. If you lift the hood and peek inside, the raiseException is implemented from setjmp(), and the code that pushes a new exception handler is implemented from longjmp(). However implemented, however, the scheme you describe, although standardly supported by nearly all languages, has extremely poor properties for building large robust software libraries. That is why so many 'modern' languages (Ada, Eiffel?, CLU, etc) feature 'true' exception handling somewhat as outlined above. -- Brad Cox; cox@stepstone.com; CI$ 71230,647; 203 426 1875 The Stepstone Corporation; 75 Glen Road; Sandy Hook CT 06482