(lispref.info)Handling Errors


Next: Error Names Prev: Processing of Errors Up: Errors

Writing Code to Handle 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.

   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 subroutines called by this form, and
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 try to handle the same error, the inner of
the two will actually handle it.

   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 continues by returning
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.

   `condition-case' 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', 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 which can be handled).

 - Special Form: condition-case VAR PROTECTED-FORM HANDLERS...
     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...)'.
     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" which describes what
     kind of error it is.  The `error-conditions' property of this
     symbol is a list of condition names (Note: Error Names.).  Emacs
     searches all the active `condition-case' forms for a handler which
     specifies one or more of these names; the innermost matching
     `condition-case' handles the error.  The handlers in this
     `condition-case' are tested in the order in which they appear.

     The body of the handler is then executed, and the `condition-case'
     returns normally, using the value of the last form in the 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, VAR is bound locally to a list of
     the form `(ERROR-SYMBOL . DATA)', giving the particulars of the
     error.  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 VAR.

     If VAR is `nil', that means no variable is bound.  Then the error
     symbol and associated data are not made available to the handler.

   Here is an example of using `condition-case' to handle the error
that results from dividing by zero.  The handler prints out a warning
message and returns a very large number.

     (defun safe-divide (dividend divisor)
       (condition-case err
           ;; Protected form.
           (/ dividend divisor)
         ;; The handler.
         (arith-error                        ; Condition.
          (princ (format "Arithmetic error: %s" 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: integer-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 `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


automatically generated by info2www