Next: restarts ignore-errors, Previous: restarts signal, Up: restarts [Index]
Evaluate body forms in a dynamic environment in which new exception
handlers are installed; it is capable of handling exceptions raised with
raise
, raise-continuable
and signal
. Basically
behave like R6RS’s guard
syntax.
The arguments ?clause must have one of the following syntaxes:
(?typespec ?condition-handler) (:no-error ?no-error-handler)
Every ?typespec is meant to be a logic predicate with the format:
?typespec = (?tag) | (and ?inner-pred0 ?inner-pred ...) | (or ?inner-pred0 ?inner-pred ...) | (xor ?inner-pred0 ?inner-pred ...) | (not ?inner-pred) ?inner-pred = ?tag | (and ?inner-pred0 ?inner-pred ...) | (or ?inner-pred0 ?inner-pred ...) | (xor ?inner-pred0 ?inner-pred ...) | (not ?inner-pred)
where: each ?tag is an identifier usable as second argument to
is-a?
; and
, or
, xor
, not
are the identifiers exported by (vicare)
.
Every ?condition-handler must be an expression evaluating to a procedure accepting a condition object as single argument; the condition object can be simple or compound.
In the no–error clause: :no-error
must be the actual symbol;
?no-error-handler must be an expression evaluating to a procedure.
The optional :no-error
clause can be present only if it is the
last one.
If the body performs a normal return:
:no-error
clause is missing: the values returned by the
body become the values returned by handler-case
.
:no-error
clause is present: the procedure
?no-error-handler is applied to the returned values; the return
values of such application become the return values of
handler-case
.
If an exception is raised (in Common Lisp jargon: a condition is signalled): a condition handler matching the raised object is searched in the sequence of clauses, left–to–right:
handler-case
.
raise-continuable
.
Usage examples:
(import (vicare) (only (vicare checks) with-result add-result)) ;;no condition (with-result (handler-case ((&error (lambda (E) (add-result 'error-handler) 1)) (&warning (lambda (E) (add-result 'warning-handler) 2))) (add-result 'body) 1)) ⇒ (1 (body)) ;;no condition, :no-error clause (with-result (handler-case ((&error (lambda (E) (add-result 'error-handler) 1)) (&warning (lambda (E) (add-result 'warning-handler) 2)) (:no-error (lambda (X) (add-result 'no-error) (* 10 X)))) (add-result 'body) 1)) ⇒ (10 (body no-error)) ;;; (internal-body ;signalled condition (define (doit C) (with-result (handler-case ((&error (lambda (E) (add-result 'error-handler) 1)) (&warning (lambda (E) (add-result 'warning-handler) 2))) (add-result 'body-begin) (signal C) (add-result 'body-normal-return)))) (doit (make-error)) ⇒ (1 (body-begin error-handler)) (doit (make-warning)) ⇒ (2 (body-begin warning-handler)) #| end of body |# ) ;;Signalled condition, multiple types in single clause. ;; (internal-body (define (doit C) (with-result (handler-case (((&error &warning) (lambda (E) (add-result 'handler) 1))) (add-result 'body-begin) (signal C) (add-result 'body-normal-return)))) (doit (make-error)) ⇒ (1 (body-begin handler)) (doit (make-warning)) ⇒ (1 (body-begin handler)) #| end of body |# ) ;;Signalled condition, nested HANDLER-CASE uses. ;; (internal-body (define (doit C) (with-result (handler-case ((&error (lambda (E) (add-result 'error-handler) 1))) (handler-case ((&warning (lambda (E) (add-result 'warning-handler) 2))) (add-result 'body-begin) (signal C) (add-result 'body-normal-return))))) (doit (make-error)) ⇒ (1 (body-begin error-handler)) (doit (make-warning)) ⇒ (2 (body-begin warning-handler)) #| end of body |# ) (internal-body ; unwind-protect (define (doit C) (with-result (handler-case ((&error (lambda (E) (add-result 'error-handler) 1))) (with-unwind-handler (lambda (why) (add-result 'outer-unwind-handler)) (lambda () (handler-case ((&warning (lambda (E) (add-result 'warning-handler) 2))) (with-unwind-handler (lambda (why) (add-result 'inner-unwind-handler)) (lambda () (add-result 'body-begin) (signal C) (add-result 'body-normal-return))))))))) (doit (make-error)) ⇒ (1 (body-begin inner-unwind-handler outer-unwind-handler error-handler)) (doit (make-warning)) ⇒ (2 (body-begin inner-unwind-handler warning-handler outer-unwind-handler)) #| end of body |# )
Next: restarts ignore-errors, Previous: restarts signal, Up: restarts [Index]