Next: , Previous: Error System, Up: Error System


16.1 Condition Signalling

Once a condition instance has been created using make-condition (or any condition constructor), it can be signalled. The act of signalling a condition is separated from the act of creating the condition to allow more flexibility in how conditions are handled. For example, a condition instance could be returned as the value of a procedure, indicating that something unusual has happened, to allow the caller to clean up some state. The caller could then signal the condition once it is ready.

A more important reason for having a separate condition-signalling mechanism is that it allows resignalling. When a signalled condition has been caught by a particular handler, and the handler decides that it doesn't want to process that particular condition, it can signal the condition again. This is one way to allow other handlers to get a chance to see the condition.

— procedure: error reason argument ...

This is the simplest and most common way to signal a condition that requires intervention before a computation can proceed (when intervention is not required, warn is more appropriate). error signals a condition (using signal-condition), and if no handler for that condition alters the flow of control (by invoking a restart, for example) it calls the procedure standard-error-handler, which normally prints an error message and stops the computation, entering an error repl. Under normal circumstances error will not return a value (although an interactive debugger can be used to force this to occur).

Precisely what condition is signalled depends on the first argument to error. If reason is a condition, then that condition is signalled and the arguments are ignored. If reason is a condition type, then a new instance of this type is generated and signalled; the arguments are used to generate the values of the fields for this condition type (they are passed as the field-plist argument to make-condition). In the most common case, however, reason is neither a condition nor a condition type, but rather a string or symbol. In this case a condition of type condition-type:simple-error is created with the message field containing the reason and the irritants field containing the arguments.

— procedure: warn reason argument ...

When a condition is not severe enough to warrant intervention, it is appropriate to signal the condition with warn rather than error. As with error, warn first calls signal-condition; the condition that is signalled is chosen exactly as in error except that a condition of type condition-type:simple-warning is signalled if reason is neither a condition nor a condition type. If the condition is not handled, warn calls the procedure standard-warning-handler, which normally prints a warning message and continues the computation by returning from warn.

warn establishes a restart named muffle-warning before calling signal-condition. This allows a signal handler to prevent the generation of the warning message by calling muffle-warning. The value of a call to warn is unspecified.

— procedure: signal-condition condition

This is the fundamental operation for signalling a condition. The precise operation of signal-condition depends on the condition type of which condition is an instance, the condition types set by break-on-signals, and the handlers established by bind-condition-handler and bind-default-condition-handler.

If the condition is an instance of a type that is a specialization of any of the types specified by break-on-signals, then a breakpoint repl is initiated. Otherwise (or when that repl returns), the handlers established by bind-condition-handler are checked, most recent first. Each applicable handler is invoked, and the search for a handler continues if the handler returns normally. If all applicable handlers return, then the applicable handlers established by bind-default-condition-handler are checked, again most recent first. Finally, if no handlers apply (or all return in a normal manner), signal-condition returns an unspecified value.

Note: unlike many other systems, the MIT/GNU Scheme runtime library does not establish handlers of any kind. (However, the Edwin text editor uses condition handlers extensively.) Thus, calls to signal-condition will return to the caller unless there are user supplied condition handlers, as the following example shows:

          (signal-condition
           (make-condition
            condition-type:error
            (call-with-current-continuation (lambda (x) x))
            '()    ; no restarts
            '()))  ; no fields
          =>  unspecified