Next: Primitive Exceptions Up: Exceptions and Control Flow Previous: Exceptions and Control Flow

# Exceptions

MzScheme supports the exception system proposed by Friedman, Haynes, and Dybvig. MzScheme's implementation extends that proposal by defining the specific exception values that are raised by each primitive error.

- `(raise exn)` raises an exception, where exn represents the exception being raised. The exn argument can be anything; it is passed to the current exception handler.
- `(current-exception-handler)` returns the current exception handler that is used by `raise`, and `(current-exception-handler f)` installs the procedure f as the current exception handler. The `current-exception-handler` procedure is a parameter; see section 9.4.1.9 for more information.

  Any procedure that takes one argument can be an exception handler, but it is an error if the exception handler returns to its caller when invoked by `raise`. (If an exception handler returns, the current error display handler and current error escape handler are called directly to report the handler's mistake.)

  The default exception handler prints an error message using the current error display handler (see `error-display-handler` in section 9.4.1.9) and then escapes by calling the current error escape handler (see `error-escape-handler` in section 9.4.1.9). If an exception is raised while an exception handler is executing, an error message is printed using a primitive error printer and the primitive error escape handler is invoked.

- `(`with-handlers` ((pred handler) ) expr )` is a syntactic form that evaluates the expr body, installing a new exception handler before evaluating the exprs and restoring the handler when a value is returned (or when control escapes from the expression). The pred and handler expressions are evaluated in the order that they are specified, before the first expr and before the exception handler is changed. The exception handler is installed and restored with `parameterize` (see section 9.4).

  The new exception handler processes an exception only if one of the pred procedures returns a true value when applied to the exception, otherwise the original exception handler is invoked (by raising the exception again). If an exception is handled by one of the handler procedures, the result of the entire `with-handlers` expression is the return value of the handler.

  When an exception is raised during the evaluation of exprs, each predicate procedure pred is applied to the exception value; if a predicate returns a true value, the corresponding handler procedure is invoked with the exception as an argument. The predicates are tried in the order that they are specified.

  Before any predicate or handler procedure is invoked, the continuation of the entire `with-handlers` expression is restored. The ``original'' exception handler (the one present before the `with-handlers` expression was evaluated) is therefore re-installed before any predicate or handler procedure is invoked.

  A particularly useful predicate procedure is `not-break-exn?`. `(not-break-exn? v)` returns `#f` if v is an instance of `exn:misc:user-break` (representing an asynchronous break exception), `#t` otherwise.

The following example defines a divide procedure that returns `+inf.0` when dividing by zero instead of signaling an exception (other exceptions raised by `/` are signaled):

      (define div-w-inf
        (lambda (n d)
          (with-handlers ([exn:application:math:zero?
                           (lambda (exn) +inf.0)])
            (/ n d))))

The following example catches and ignores file exceptions, but lets the enclosing context handle breaks:

      (define (file-date-if-there filename)
        (with-handlers ([not-break-exn? (lambda (exn) #f)])
          (file-or-directory-modify-seconds filename)))

- Primitive Exceptions

Next: Primitive Exceptions Up: Exceptions and Control Flow Previous: Exceptions and Control Flow