Next: Error Symbols, Previous: Processing of Errors, Up: Errors
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. (You can use the macro
ignore-errors
for a simple case like this; see below.)
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.
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.
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. You can also specify that a particular handler
should let the debugger run first, by writing debug
among the
conditions, like this:
(condition-case nil (delete-file filename) ((debug error) nil))
The effect of debug
here is only to prevent
condition-case
from suppressing the call to the debugger. Any
given error will invoke the debugger only if debug-on-error
and
the other usual filtering mechanisms say it should. See Error Debugging.
The macro
condition-case-unless-debug
provides another way to handle debugging of such forms. It behaves exactly likecondition-case
, unless the variabledebug-on-error
is non-nil
, in which case it does not handle any errors at all.
Once Emacs decides that a certain handler handles the error, it
returns control to that handler. To do so, Emacs unbinds all variable
bindings made by binding constructs that are being exited, and
executes the cleanups of all unwind-protect
forms that are
being exited. Once control arrives at the handler, the body of the
handler executes normally.
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.
Error signaling and handling have some resemblance to throw
and
catch
(see 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, thecondition-case
has no effect. Thecondition-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 (which can includedebug
to allow the debugger to run before the handler); 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, and which describes also a list of condition names (see Error Symbols). Emacs searches all the active
condition-case
forms for a handler that specifies one or more of these condition names; the innermost matchingcondition-case
handles the error. Within thiscondition-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.Sometimes it is necessary to re-throw a signal caught by
condition-case
, for some outer-level handler to catch. Here's how to do that:(signal (car err) (cdr err))where
err
is the error description variable, the first argument tocondition-case
whose error condition you want to re-throw. See Definition of signal.
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. See 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 (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 from error
:
(setq baz 34)
⇒ 34
(condition-case err
(if (eq baz 35)
t
;; This is a call to the function error
.
(error "Rats! The variable %s was %s, not 35" 'baz baz))
;; This is the handler; it is not a form.
(error (princ (format "The error was: %s" err))
2))
-| The error was: (error "Rats! The variable baz was 34, not 35")
⇒ 2
This construct executes body, ignoring any errors that occur during its execution. If the execution is without error,
ignore-errors
returns the value of the last form in body; otherwise, it returnsnil
.Here's the example at the beginning of this subsection rewritten using
ignore-errors
:(ignore-errors (delete-file filename))
This macro is like a milder version of
ignore-errors
. Rather than suppressing errors altogether, it converts them into messages. It uses the string format to format the message. format should contain a single ‘%’-sequence; e.g.,"Error: %S"
. Usewith-demoted-errors
around code that is not expected to signal errors, but should be robust if one does occur. Note that this macro usescondition-case-unless-debug
rather thancondition-case
.