@c -*-texinfo-*-
@c This is part of the XEmacs Lisp Reference Manual.
-@c Copyright (C) 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+@c Copyright (C) 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
@c See the file lispref.texi for copying conditions.
@setfilename ../../info/control.info
@node Control Structures, Variables, Evaluation, Top
non-@code{nil}, @var{then-form} is evaluated and the result returned.
Otherwise, the @var{else-forms} are evaluated in textual order, and the
value of the last one is returned. (The @var{else} part of @code{if} is
-an example of an implicit @code{progn}. @xref{Sequencing}.)
+an example of an implicit @code{progn}. @xref{Sequencing}.)
If @var{condition} has the value @code{nil}, and no @var{else-forms} are
given, @code{if} returns @code{nil}.
@example
@group
-(if nil
- (print 'true)
+(if nil
+ (print 'true)
'very-false)
@result{} very-false
@end group
never @code{nil}, so this clause never fails, provided the @code{cond}
gets to it at all.
-For example,
+For example,
@example
@group
@example
@group
(if @var{arg1} @var{arg1}
- (if @var{arg2} @var{arg2}
+ (if @var{arg2} @var{arg2}
@var{arg3}))
@end group
@end example
@end group
@group
-(catch 'hack
+(catch 'hack
(print (catch2 'hack))
'no)
@print{} yes
which you call for other purposes, such as if you try to take the
@sc{car} of an integer or move forward a character at the end of the
buffer; you can also signal errors explicitly with the functions
-@code{error} and @code{signal}.
+@code{error}, @code{signal}, and others.
- Quitting, which happens when the user types @kbd{C-g}, is not
+ Quitting, which happens when the user types @kbd{C-g}, is not
considered an error, but it is handled almost like an error.
@xref{Quitting}.
-@defun error format-string &rest args
-This function signals an error with an error message constructed by
-applying @code{format} (@pxref{String Conversion}) to
-@var{format-string} and @var{args}.
+XEmacs has a rich hierarchy of error symbols predefined via @code{deferror}.
+
+@example
+error
+ syntax-error
+ invalid-read-syntax
+ list-formation-error
+ malformed-list
+ malformed-property-list
+ circular-list
+ circular-property-list
+
+ invalid-argument
+ wrong-type-argument
+ args-out-of-range
+ wrong-number-of-arguments
+ invalid-function
+ no-catch
+
+ invalid-state
+ void-function
+ cyclic-function-indirection
+ void-variable
+ cyclic-variable-indirection
+
+ invalid-operation
+ invalid-change
+ setting-constant
+ editing-error
+ beginning-of-buffer
+ end-of-buffer
+ buffer-read-only
+ io-error
+ end-of-file
+ arith-error
+ range-error
+ domain-error
+ singularity-error
+ overflow-error
+ underflow-error
+@end example
+
+The five most common errors you will probably use or base your new
+errors off of are @code{syntax-error}, @code{invalid-argument},
+@code{invalid-state}, @code{invalid-operation}, and
+@code{invalid-change}. Note the semantic differences:
+
+@itemize @bullet
+@item
+@code{syntax-error} is for errors in complex structures: parsed strings,
+lists, and the like.
+
+@item
+@code{invalid-argument} is for errors in a simple value. Typically, the
+entire value, not just one part of it, is wrong.
+
+@item
+@code{invalid-state} means that some settings have been changed in such
+a way that their current state is unallowable. More and more, code is
+being written more carefully, and catches the error when the settings
+are being changed, rather than afterwards. This leads us to the next
+error:
+
+@item
+@code{invalid-change} means that an attempt is being made to change some
+settings into an invalid state. @code{invalid-change} is a type of
+@code{invalid-operation}.
+
+@item
+@code{invalid-operation} refers to all cases where code is trying to do
+something that's disallowed. This includes file errors, buffer errors
+(e.g. running off the end of a buffer), @code{invalid-change} as just
+mentioned, and arithmetic errors.
+@end itemize
+
+@defun error datum &rest args
+This function signals a non-continuable error.
+
+@var{datum} should normally be an error symbol, i.e. a symbol defined
+using @code{define-error}. @var{args} will be made into a list, and
+@var{datum} and @var{args} passed as the two arguments to @code{signal},
+the most basic error handling function.
+
+This error is not continuable: you cannot continue execution after the
+error using the debugger @kbd{r} command. See also @code{cerror}.
+
+The correct semantics of @var{args} varies from error to error, but for
+most errors that need to be generated in Lisp code, the first argument
+should be a string describing the *context* of the error (i.e. the exact
+operation being performed and what went wrong), and the remaining
+arguments or \"frobs\" (most often, there is one) specify the offending
+object(s) and/or provide additional details such as the exact error when
+a file error occurred, e.g.:
+
+@itemize @bullet
+@item
+the buffer in which an editing error occurred.
+@item
+an invalid value that was encountered. (In such cases, the string
+should describe the purpose or \"semantics\" of the value [e.g. if the
+value is an argument to a function, the name of the argument; if the value
+is the value corresponding to a keyword, the name of the keyword; if the
+value is supposed to be a list length, say this and say what the purpose
+of the list is; etc.] as well as specifying why the value is invalid, if
+that's not self-evident.)
+@item
+the file in which an error occurred. (In such cases, there should be a
+second frob, probably a string, specifying the exact error that occurred.
+This does not occur in the string that precedes the first frob, because
+that frob describes the exact operation that was happening.
+@end itemize
+
+For historical compatibility, DATUM can also be a string. In this case,
+@var{datum} and @var{args} are passed together as the arguments to
+@code{format}, and then an error is signalled using the error symbol
+@code{error} and formatted string. Although this usage of @code{error}
+is very common, it is deprecated because it totally defeats the purpose
+of having structured errors. There is now a rich set of defined errors
+to use.
+
+See also @code{cerror}, @code{signal}, and @code{signal-error}."
These examples show typical uses of @code{error}:
@example
@group
-(error "You have committed an error.
+(error 'syntax-error
+ "Dialog descriptor must supply at least one button"
+ descriptor)
+@end group
+
+@group
+(error "You have committed an error.
Try something else.")
- @error{} You have committed an error.
+ @error{} You have committed an error.
Try something else.
@end group
@group
(error "You have committed %d errors." 10)
- @error{} You have committed 10 errors.
+ @error{} You have committed 10 errors.
@end group
@end example
-@code{error} works by calling @code{signal} with two arguments: the
-error symbol @code{error}, and a list containing the string returned by
-@code{format}.
-
If you want to use your own string as an error message verbatim, don't
just write @code{(error @var{string})}. If @var{string} contains
@samp{%}, it will be interpreted as a format specifier, with undesirable
results. Instead, use @code{(error "%s" @var{string})}.
@end defun
+@defun cerror datum &rest args
+This function behaves like @code{error}, except that the error it
+signals is continuable. That means that debugger commands @kbd{c} and
+@kbd{r} can resume execution.
+@end defun
+
@defun signal error-symbol data
-This function signals an error named by @var{error-symbol}. The
-argument @var{data} is a list of additional Lisp objects relevant to the
-circumstances of the error.
+This function signals a continuable error named by @var{error-symbol}.
+The argument @var{data} is a list of additional Lisp objects relevant to
+the circumstances of the error.
The argument @var{error-symbol} must be an @dfn{error symbol}---a symbol
bearing a property @code{error-conditions} whose value is a list of
errors.
The number and significance of the objects in @var{data} depends on
-@var{error-symbol}. For example, with a @code{wrong-type-arg} error,
-there are two objects in the list: a predicate that describes the type
-that was expected, and the object that failed to fit that type.
+@var{error-symbol}. For example, with a @code{wrong-type-argument}
+error, there are two objects in the list: a predicate that describes the
+type that was expected, and the object that failed to fit that type.
@xref{Error Symbols}, for a description of error symbols.
Both @var{error-symbol} and @var{data} are available to any error
@var{data})} (@pxref{Handling Errors}). If the error is not handled,
these two values are used in printing the error message.
-The function @code{signal} never returns (though in older Emacs versions
-it could sometimes return).
+The function @code{signal} can return, if the debugger is invoked and
+the user invokes the ``return from signal'' option. If you want the
+error not to be continuable, use @code{signal-error} instead. Note that
+in FSF Emacs @code{signal} never returns.
@smallexample
@group
@end group
@group
-(signal 'no-such-error '("My unknown error condition."))
- @error{} peculiar error: "My unknown error condition."
+(signal 'no-such-error '("My unknown error condition"))
+ @error{} Peculiar error (no-such-error "My unknown error condition")
@end group
@end smallexample
@end defun
-@cindex CL note---no continuable errors
-@quotation
-@b{Common Lisp note:} XEmacs Lisp has nothing like the Common Lisp
-concept of continuable errors.
-@end quotation
+@defun signal-error error-symbol data
+This function behaves like @code{signal}, except that the error it
+signals is not continuable.
+@end defun
+
+@defmac check-argument-type predicate argument
+This macro checks that @var{argument} satisfies @var{predicate}. If
+that is not the case, it signals a continuable
+@code{wrong-type-argument} error until the returned value satisfies
+@var{predicate}, and assigns the returned value to @var{argument}. In
+other words, execution of the program will not continue until
+@var{predicate} is met.
+
+@var{argument} is not evaluated, and should be a symbol.
+@var{predicate} is evaluated, and should name a function.
+
+As shown in the following example, @code{check-argument-type} is useful
+in low-level code that attempts to ensure the sanity of its data before
+proceeding.
+
+@example
+@group
+(defun cache-object-internal (object wlist)
+ ;; @r{Before doing anything, make sure that @var{wlist} is indeed}
+ ;; @r{a weak list, which is what we expect.}
+ (check-argument-type 'weak-list-p wlist)
+ @dots{})
+@end group
+@end example
+@end defmac
@node Processing of Errors
@subsubsection How XEmacs Processes Errors
command loop's handler uses the error symbol and associated data to
print an error message.
+Errors in command loop are processed using the @code{command-error}
+function, which takes care of some necessary cleanup, and prints a
+formatted error message to the echo area. The functions that do the
+formatting are explained below.
+
+@defun display-error error-object stream
+This function displays @var{error-object} on @var{stream}.
+@var{error-object} is a cons of error type, a symbol, and error
+arguments, a list. If the error type symbol of one of its error
+condition superclasses has a @code{display-error} property, that
+function is invoked for printing the actual error message. Otherwise,
+the error is printed as @samp{Error: arg1, arg2, ...}.
+@end defun
+
+@defun error-message-string error-object
+This function converts @var{error-object} to an error message string,
+and returns it. The message is equivalent to the one that would be
+printed by @code{display-error}, except that it is conveniently returned
+in string form.
+@end defun
+
@cindex @code{debug-on-error} use
An error that has no explicit handler may call the Lisp debugger. The
debugger is enabled if the variable @code{debug-on-error} (@pxref{Error
totally unpredictable, such as when the program evaluates an expression
read from the user.
+@cindex @code{debug-on-signal} use
+ Even when an error is handled, the debugger may still be called if the
+variable @code{debug-on-signal} (@pxref{Error Debugging}) is
+non-@code{nil}. Note that this may yield unpredictable results with
+code that traps expected errors as normal part of its operation. Do not
+set @code{debug-on-signal} unless you know what you are doing.
+
Error signaling and handling have some resemblance to @code{throw} and
@code{catch}, but they are entirely separate facilities. An error
cannot be caught by a @code{catch}, and a @code{throw} cannot be handled
@smallexample
@group
(defun safe-divide (dividend divisor)
- (condition-case err
+ (condition-case err
;; @r{Protected form.}
- (/ dividend divisor)
+ (/ dividend divisor)
;; @r{The handler.}
(arith-error ; @r{Condition.}
(princ (format "Arithmetic error: %s" err))
@end smallexample
@noindent
-The handler specifies condition name @code{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 @code{condition-case}. Thus,
+The handler specifies condition name @code{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 @code{condition-case}. Thus,
@smallexample
@group
;; @r{This is a call to the function @code{error}.}
(error "Rats! The variable %s was %s, not 35" 'baz baz))
;; @r{This is the handler; it is not a form.}
- (error (princ (format "The error was: %s" err))
+ (error (princ (format "The error was: %s" err))
2))
@print{} The error was: (error "Rats! The variable baz was 34, not 35")
@result{} 2
is distinct from @code{error}, and perhaps some intermediate
classifications.
- In order for a symbol to be an error symbol, it must have an
-@code{error-conditions} property which gives a list of condition names.
-This list defines the conditions that this kind of error belongs to.
-(The error symbol itself, and the symbol @code{error}, should always be
-members of this list.) Thus, the hierarchy of condition names is
-defined by the @code{error-conditions} properties of the error symbols.
-
- In addition to the @code{error-conditions} list, the error symbol
-should have an @code{error-message} property whose value is a string to
-be printed when that error is signaled but not handled. If the
-@code{error-message} property exists, but is not a string, the error
-message @samp{peculiar error} is used.
-@cindex peculiar error
+ In other words, each error condition @dfn{inherits} from another error
+condition, with @code{error} sitting at the top of the inheritance
+hierarchy.
+
+@defun define-error error-symbol error-message &optional inherits-from
+ This function defines a new error, denoted by @var{error-symbol}.
+@var{error-message} is an informative message explaining the error, and
+will be printed out when an unhandled error occurs. @var{error-symbol}
+is a sub-error of @var{inherits-from} (which defaults to @code{error}).
+
+ @code{define-error} internally works by putting on @var{error-symbol}
+an @code{error-message} property whose value is @var{error-message}, and
+an @code{error-conditions} property that is a list of @var{error-symbol}
+followed by each of its super-errors, up to and including @code{error}.
+You will sometimes see code that sets this up directly rather than
+calling @code{define-error}, but you should @emph{not} do this yourself,
+unless you wish to maintain compatibility with FSF Emacs, which does not
+provide @code{define-error}.
+@end defun
- Here is how we define a new error symbol, @code{new-error}:
+ Here is how we define a new error symbol, @code{new-error}, that
+belongs to a range of errors called @code{my-own-errors}:
@example
@group
-(put 'new-error
- 'error-conditions
- '(error my-own-errors new-error))
-@result{} (error my-own-errors new-error)
-@end group
-@group
-(put 'new-error 'error-message "A new error")
-@result{} "A new error"
+(define-error 'my-own-errors "A whole range of errors" 'error)
+(define-error 'new-error "A new error" 'my-own-errors)
@end group
@end example
@noindent
-This error has three condition names: @code{new-error}, the narrowest
-classification; @code{my-own-errors}, which we imagine is a wider
-classification; and @code{error}, which is the widest of all.
+@code{new-error} has three condition names: @code{new-error}, the
+narrowest classification; @code{my-own-errors}, which we imagine is a
+wider classification; and @code{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
+@code{new-error} before @code{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 @code{new-error} on its own; only
an explicit call to @code{signal} (@pxref{Signaling Errors}) in your
code can do this:
when you write an error handler. Using error symbols alone would
eliminate all but the narrowest level of classification.
+
+
@xref{Standard Errors}, for a list of all the standard error symbols
and their conditions.