[ < ] | [ > ] | [ << ] | [Plus haut] | [ >> ] | [Top] | [Table des matières] | [Index] | [ ? ] |
The usual effect of signaling an error is to terminate the command that is
running and return immediately to the Emacs editor command loop. You can
arrange to trap errors occurring in a part of your program by establishing
an error handler, with the special form condition-case
. A simple
example looks like this:
(condition-case nil (delete-file filename) (error nil)) |
This deletes the file named filename, catching any error and returning
nil
if an error occurs.
The second argument of condition-case
is called the protected
form. (In the example above, the protected form is a call to
delete-file
.) The error handlers go into effect when this form
begins execution and are deactivated when this form returns. They remain in
effect for all the intervening time. In particular, they are in effect
during the execution of functions called by this form, in their subroutines,
and so on. This is a good thing, since, strictly speaking, errors can be
signaled only by Lisp primitives (including signal
and error
)
called by the protected form, not by the protected form itself.
The arguments after the protected form are handlers. Each handler lists one
or more condition names (which are symbols) to specify which errors it
will handle. The error symbol specified when an error is signaled also
defines a list of condition names. A handler applies to an error if they
have any condition names in common. In the example above, there is one
handler, and it specifies one condition name, error
, which covers all
errors.
The search for an applicable handler checks all the established handlers
starting with the most recently established one. Thus, if two nested
condition-case
forms offer to handle the same error, the inner of the
two gets to handle it.
If an error is handled by some condition-case
form, this ordinarily
prevents the debugger from being run, even if debug-on-error
says
this error should invoke the debugger. Voir la section Entering the Debugger on an Error. If you want
to be able to debug errors that are caught by a condition-case
, set
the variable debug-on-signal
to a non-nil
value.
When an error is handled, control returns to the handler. Before this
happens, Emacs unbinds all variable bindings made by binding constructs that
are being exited and executes the cleanups of all unwind-protect
forms that are exited. Once control arrives at the handler, the body of the
handler is executed.
After execution of the handler body, execution returns from the
condition-case
form. Because the protected form is exited completely
before execution of the handler, the handler cannot resume execution at the
point of the error, nor can it examine variable bindings that were made
within the protected form. All it can do is clean up and proceed.
The condition-case
construct is often used to trap errors that are
predictable, such as failure to open a file in a call to
insert-file-contents
. It is also used to trap errors that are
totally unpredictable, such as when the program evaluates an expression read
from the user.
Error signaling and handling have some resemblance to throw
and
catch
(voir la section Explicit Nonlocal Exits: catch
and throw
), but they are entirely separate
facilities. An error cannot be caught by a catch
, and a throw
cannot be handled by an error handler (though using throw
when there
is no suitable catch
signals an error that can be handled).
This special form establishes the error handlers handlers around the
execution of protected-form. If protected-form executes without
error, the value it returns becomes the value of the condition-case
form; in this case, the condition-case
has no effect. The
condition-case
form makes a difference when an error occurs during
protected-form.
Each of the handlers is a list of the form (conditions
body…)
. Here conditions is an error condition name to be
handled, or a list of condition names; body is one or more Lisp
expressions to be executed when this handler handles an error. Here are
examples of handlers:
(error nil) (arith-error (message "Division by zero")) ((arith-error file-error) (message "Either division by zero or failure to open a file")) |
Each error that occurs has an error symbol that describes what kind of
error it is. The error-conditions
property of this symbol is a list
of condition names (voir la section Error Symbols and Condition Names). Emacs searches all the active
condition-case
forms for a handler that specifies one or more of
these condition names; the innermost matching condition-case
handles
the error. Within this condition-case
, the first applicable handler
handles the error.
After executing the body of the handler, the condition-case
returns
normally, using the value of the last form in the handler body as the
overall value.
The argument var is a variable. condition-case
does not bind
this variable when executing the protected-form, only when it handles
an error. At that time, it binds var locally to an error
description, which is a list giving the particulars of the error. The
error description has the form (error-symbol . data)
.
The handler can refer to this list to decide what to do. For example, if
the error is for failure opening a file, the file name is the second element
of data—the third element of the error description.
If var is nil
, that means no variable is bound. Then the error
symbol and associated data are not available to the handler.
This function returns the error message string for a given error descriptor. It is useful if you want to handle an error by printing the usual error message for that error. Voir Definition of signal.
Here is an example of using condition-case
to handle the error that
results from dividing by zero. The handler displays the error message (but
without a beep), then returns a very large number.
(defun safe-divide (dividend divisor) (condition-case err ;; Protected form. (/ dividend divisor) ;; The handler. (arith-error ; Condition. ;; Display the usual message for this error. (message "%s" (error-message-string err)) 1000000))) ⇒ safe-divide (safe-divide 5 0) -| Arithmetic error: (arith-error) ⇒ 1000000 |
The handler specifies condition name arith-error
so that it will
handle only division-by-zero errors. Other kinds of errors will not be
handled, at least not by this condition-case
. Thus,
(safe-divide nil 3) error--> Wrong type argument: number-or-marker-p, nil |
Here is a condition-case
that catches all kinds of errors, including
those signaled with error
:
(setq baz 34)
⇒ 34
(condition-case err
(if (eq baz 35)
t
;; This is a call to the function |
[ < ] | [ > ] | [ << ] | [Plus haut] | [ >> ] | [Top] | [Table des matières] | [Index] | [ ? ] |
Ce document a été généré par Eric Reinbold le 13 Octobre 2007 en utilisant texi2html 1.78.