4.6 The errorHandlerpattern

The errorHandler supports flexible handling of network related errors. An errorHandler effectively defines a dynamic scope in which network errors may be caught and handled.

A dynamic chain of error handlers is maintained for each systemenv system coroutine (see [MIA 90-08]). On entry to an errorHandler, default is to push the handler entered onto the front of the dynamic chain of error handlers related to the current system, thereby making it the active errorHandler. Likewise, when the errorHandler is left, it is removed from the dynamic chain of error handlers, and the previously active errorHandler becomes active again.

When a network related error occurs, a corresponding exception is raised in the active errorHandler. If the active error handler does not further bind the exception raised, the exception is automatically propagated to the previous handler in the dynamic chain. The propagation of an exception continues until either some handler catches the exception (by further binding the corresponding errorHandler virtual), or until the end of the dynamic chain is reached. If that happens, the exception is propagated to the globalHandler. If even the globalHandler does not catch the error, default action is to kill the current shell. If an error occurs in a coroutine that never entered an errorHandler, the corresponding exception is raised directly in the globalHandler.

Note that by default each system coroutine has its own dynamic error handler chain. If the top of this chain is reached, control is passed to the globalHandler, and not, for example, to the handler chain of the system that forked the failing coroutine.

As described above, default is to push a newly entered errorHandler onto the currently active chain of error handlers. This means that exceptions not handled by some errorHandler eh are automatically propagated to the errorHandler that was active before entry to eh and, if eh was the first errorHandler entered by the current system coroutine, errors not handled by eh are propagated to the global handler. However, this default may be changed by supplying an errorHandler (prevHandler) as enter parameter when entering a new errorHandler eh. This way, exceptions not handled by eh will be propagated to prevHandler. As an example, this may be used to transfer errors automatically from a coroutine to the creator of that coroutine.

The error pattern is an abstract super pattern for all communication exception virtuals. The virtual subpatterns of error thus correspond to different kinds of network errors, as described in the next section.

4.6.1 Error types

The network errors handled by the subpatterns of error inside errorHandler are the following.

4.6.2 Error handling

To handle network errors, further bind the corresponding error virtual as listed above. Within further bindings, one of the patterns ignore, continue or abort should be called as the last action. Note that if there are imperatives following the call to e.g. continue, they will not be executed! ignore, continue and abort are described below.

do myLabel: errorHandler
     (# connectionFailed:: 
          (# 
          do abort (# do leave myLabel #)
          #);
     do server.op1; ...; server.opn;
     #);
do myLabel: errorHandler
     (# connectionFailed:: 
          (# 
          do leave myLabel
          #);
     do server.op1; ...; server.opn;
     #);
do errorHandler
   (# connectionFailed:: (# do ignore #);
   do server1.op1; server2.op2;
   #);

In order to maintain the errorHandler chain, it is not allowed to leave the dopart of an errorHandler directly. Leaving an errorHandler must be done from inside the dopart of a leaveHandler:

do someLabel: errorHandler
   (#
   do ...;
      leaveHandler (# do leave someLabel #)
   #);

However, from inside the error.abort pattern, the errorHandler currently handling the error may be left directly, as was shown in the abort example above.

Notice! Notice: It is not allowed to leave the dopart of an errorHandler outside the scope of a leaveHandler.

If multiple errorHandlers are left simultaneously, the leaveHandler nested inside the outermost errorHandler in the dynamic call chain must be used. For example:

do e1: errorHandler
   (# leaveFirst: leaveHandler (# do INNER #);
   do e2: errorHandler
      (# leaveSecond: leaveHandler (# do INNER #)
      do e3: errorHandler
         (#
         do leaveFirst (# do leave e1 #);
         #)
      #)
   #);


Distributed Objects in BETA - Reference Manual
© 1993-2002 Mjølner Informatics
[Modified: Monday October 23rd 2000 at 11:16]