+File: lispref.info, Node: Handling Errors, Next: Error Symbols, 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 XEmacs 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 will actually handle it.
+
+ When an error is handled, control returns to the handler. Before
+this happens, XEmacs 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.
+
+ Even when an error is handled, the debugger may still be called if
+the variable `debug-on-signal' (*note Error Debugging::) is non-`nil'.
+Note that this may yield unpredictable results with code that traps
+expected errors as normal part of its operation. Do not set
+`debug-on-signal' unless you know what you are doing.
+
+ 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 that 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...)'.
+ 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 (*note Error Symbols::). 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 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 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
+
+\1f
+File: lispref.info, Node: Error Symbols, Prev: Handling Errors, Up: Errors
+
+Error Symbols and Condition Names
+.................................
+
+ When you signal an error, you specify an "error symbol" to specify
+the kind of error you have in mind. Each error has one and only one
+error symbol to categorize it. This is the finest classification of
+errors defined by the XEmacs Lisp language.
+
+ These narrow classifications are grouped into a hierarchy of wider
+classes called "error conditions", identified by "condition names".
+The narrowest such classes belong to the error symbols themselves: each
+error symbol is also a condition name. There are also condition names
+for more extensive classes, up to the condition name `error' which
+takes in all kinds of errors. Thus, each error has one or more
+condition names: `error', the error symbol if that is distinct from
+`error', and perhaps some intermediate classifications.
+
+ In other words, each error condition "inherits" from another error
+condition, with `error' sitting at the top of the inheritance hierarchy.
+
+ - Function: define-error error-symbol error-message &optional
+ inherits-from
+ This function defines a new error, denoted by ERROR-SYMBOL.
+ ERROR-MESSAGE is an informative message explaining the error, and
+ will be printed out when an unhandled error occurs. ERROR-SYMBOL
+ is a sub-error of INHERITS-FROM (which defaults to `error').
+
+ `define-error' internally works by putting on ERROR-SYMBOL an
+ `error-message' property whose value is ERROR-MESSAGE, and an
+ `error-conditions' property that is a list of ERROR-SYMBOL
+ followed by each of its super-errors, up to and including `error'.
+ You will sometimes see code that sets this up directly rather than
+ calling `define-error', but you should _not_ do this yourself,
+ unless you wish to maintain compatibility with FSF Emacs, which
+ does not provide `define-error'.
+
+ Here is how we define a new error symbol, `new-error', that belongs
+to a range of errors called `my-own-errors':
+
+ (define-error 'my-own-errors "A whole range of errors" 'error)
+ (define-error 'new-error "A new error" 'my-own-errors)
+
+`new-error' has three condition names: `new-error', the narrowest
+classification; `my-own-errors', which we imagine is a wider
+classification; and `error', which is the widest of all.
+
+ Note that it is not legal to try to define an error unless its
+super-error is also defined. For instance, attempting to define
+`new-error' before `my-own-errors' are defined will signal an error.
+
+ The error string should start with a capital letter but it should
+not end with a period. This is for consistency with the rest of Emacs.
+
+ Naturally, XEmacs will never signal `new-error' on its own; only an
+explicit call to `signal' (*note Signaling Errors::) in your code can
+do this:
+
+ (signal 'new-error '(x y))
+ error--> A new error: x, y
+
+ This error can be handled through any of the three condition names.
+This example handles `new-error' and any other errors in the class
+`my-own-errors':
+
+ (condition-case foo
+ (bar nil t)
+ (my-own-errors nil))
+
+ The significant way that errors are classified is by their condition
+names--the names used to match errors with handlers. An error symbol
+serves only as a convenient way to specify the intended error message
+and list of condition names. It would be cumbersome to give `signal' a
+list of condition names rather than one error symbol.
+
+ By contrast, using only error symbols without condition names would
+seriously decrease the power of `condition-case'. Condition names make
+it possible to categorize errors at various levels of generality when
+you write an error handler. Using error symbols alone would eliminate
+all but the narrowest level of classification.
+
+ *Note Standard Errors::, for a list of all the standard error symbols
+and their conditions.
+
+\1f