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.
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 220.127.116.11) and then escapes by calling the current error escape handler (see error-escape-handler in section 18.104.22.168). 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.
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.
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)))