Next: Ignoring Errors, Previous: Error Processing—Error Debugging, Up: Errors—Unintentional Nonlocal Exits [Index]
condition-case special form
debug-on-error variable
debug-on-signal variable
error-message-string function
You can arrange to trap ‘errors’ occurring in a part of your program by
establishing an ‘error handler’, with the special form condition-case.
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. 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.
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.
Each of the ‘HANDLER’ s is a list of the form (conditions body…).
‘CONDITIONS’ is an error condition name to be handled, or a list of
condition names (which can include debug to allow the debugger to run
before the handler). A condition name of ‘t’ matches any condition.
‘BODY’ is one or more Lisp expressions to be executed when this handler handles an error.
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. 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.
(condition-case nil
(delete-file filename)
(error nil))
Listing F.3: Simple condition-case Example
This catches any ‘error’ on file deletion and returns ‘nil’. You can also use
the macro ignore-errors in a simple case like this.
condition-case is called the protected form. 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.
signal and error) called by the protected form.
condition-case, set the variable debug-on-signal to a non-‘nil’ value.
(condition-case nil
(delete-file filename)
((debug error) nil))
Listing F.4: Run Debugger First on File Deletion
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.
(error nil) (arith-error (message "Division by zero")) ((arith-error file-error) (message "Either division by zero or failure to open a file"))
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. 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).
(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
(safe-divide nil 3)
error→ Wrong type argument: number-or-marker-p, nil
Listing F.5: Handling a Specific Error
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
Listing F.6: Handling All Errors
condition-case-unless-debug MacroThe macro condition-case-unless-debug provides another way to handle
debugging of such forms. It behaves exactly like condition-case, unless the
variable debug-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.
unwind-protect forms that are being
exited.
error-message-string FunctionThis 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.
Error signaling and handling have some resemblance to throw and catch but
they are entirely separate facilities: An ‘error’ cannot be caught by a
catch, and a throw cannot be handled by an error handler.
throw when there is no suitable catch signals an ‘error’ that can
be handled.
Next: Ignoring Errors, Previous: Error Processing—Error Debugging, Up: Errors—Unintentional Nonlocal Exits [Index]