Common Lisp the Language, 2nd Edition
Next: Specialized
Error-Signaling Forms Up: Errors Previous: Errors
The functions in this section provide various mechanisms for signaling warnings, breaks, continuable errors, and fatal errors.
In each case, the caller specifies an error message (a string) that
may be processed (and perhaps displayed to the user) by the
error-handling mechanism. All messages are constructed by applying the
function format
to the quantities nil
,
format-string, and all the args to produce a
string.
An error message string should not contain a newline character at either the beginning or end, and should not contain any sort of herald indicating that it is an error. The system will take care of these according to whatever its preferred style may be.
Conventionally, error messages are complete English sentences ending with a period. Newlines in the middle of long messages are acceptable. There should be no indentation after a newline in the middle of an error message. The error message need not mention the name of the function that signals the error; it is assumed that the debugger will make this information available.
Implementation note: If the debugger in a particular
implementation displays error messages indented from the prevailing left
margin (for example, indented by seven spaces because they are prefixed
by the seven-character herald ``Error:
’’), then the
debugger should take care of inserting the appropriate indentation into
a multi-line error message. Similarly, a debugger that prefixes error
messages with semicolons so that they appear to be comments should take
care of inserting a semicolon at the beginning of each line in a
multi-line error message. These rules are suggested because, even within
a single implementation, there may be more than one program that
presents error messages to the user, and they may use different styles
of presentation. The caller of error
cannot anticipate all
such possible styles, and so it is incumbent upon the presenter of the
message to make any necessary adjustments.
Common Lisp does not specify the manner in which error messages and
other messages are displayed. For the purposes of exposition, a fairly
simple style of textual presentation will be used in the examples in
this chapter. The character >
is used to represent the
command prompt symbol for a debugger.
[Function]
error
format-string
&rest
args
This function signals a fatal error. It is impossible to continue from
this kind of error; thus error
will never return to its
caller.
The debugger printout in the following example is typical of what an
implementation might print when error
is called. Suppose
that the (misspelled) symbol emergnecy-shutdown
has no
property named command
(all too likely, as it is probably a
typographical error for emergency-shutdown
).
(defun command-dispatch (cmd)
(let ((fn (get cmd 'command)))
(if (not (null fn))
(funcall fn))
(error "The command ~S is unrecognized." cmd))))
(command-dispatch 'emergnecy-shutdown)
Error: The command EMERGNECY-SHUTDOWN is unrecognized.
Error signaled by function COMMAND-DISPATCH.
>
X3J13 voted in June 1988 (CONDITION-SYSTEM) to adopt a proposal for a
Common Lisp Condition System. This proposal modifies the definition of
error
to specify its interaction with the condition system.
See section 29.4.1.
Compatibility note: Lisp Machine Lisp calls this
function ferror
. MacLisp has a function named
error
that takes different arguments and can signal either
a fatal or a continuable error.
[Function]
cerror
continue-format-string
error-format-string
&rest
args
cerror
is used to signal continuable errors. Like
error
, it signals an error and enters the debugger.
However, cerror
allows the program to be continued from the
debugger after resolving the error.
If the program is continued after encountering the error,
cerror
returns nil
. The code that follows the
call to cerror
will then be executed. This code should
correct the problem, perhaps by accepting a new value from the user if a
variable was invalid.
If the code that corrects the problem interacts with the program’s
use and might possibly be misled, it should make sure the error has
really been corrected before continuing. One way to do this is to put
the call to cerror
and the correction code in a loop,
checking each time to see if the error has been corrected before
terminating the loop.
The continue-format-string argument, like the
error-format-string argument, is given as a control string to
format
along with the args to construct a message
string. The error message string is used in the same way that
error
uses it. The continue message string should describe
the effect of continuing. The intent is that this message can be
displayed as an aid to the user in deciding whether and how to continue.
For example, it might be used by an interactive debugger as part of the
documentation of its ``continue’’ command.
The content of the continue message should adhere to the rules of
style for error messages. It should not include any statement of how the
``continue’’ command is given, since this may be different for each
debugger. (It is up to the debugger to supply this information according
to its own particular style of presentation and user interaction.)
X3J13 voted in June 1988 (CONDITION-SYSTEM) to adopt a proposal for a
Common Lisp Condition System. This proposal modifies the definition of
cerror
to specify its interaction with the condition
system. See section 29.4.1.
Here is an example where the caller of cerror
, if
continued, fixes the problem without any further user interaction:
(let ((nvals (list-length vals)))
(unless (= nvals 3)
(cond ((< nvals 3)
(cerror "Assume missing values are zero."
"Too few values in ~S;~%~
three are required, ~
but ~R ~:[were~;was~] supplied."
nvals (= nvals 1))
(setq vals (append vals (subseq '(0 0 0) nvals))))
(t (cerror "Ignore all values after the first three."
"Too many values in ~S;~%~
three are required, ~
but ~R were supplied."
nvals)
(setq vals (subseq vals 0 3))))))
If vals
were the list (-47)
, the
interaction might look like this:
Error: Too few values in (-47);
three are required, but one was supplied.
Error signaled by function EXAMPLE.
If continued: Assume missing values are zero.
>
In this example, a loop is used to ensure that a test is satisfied.
(This example could be written more succinctly using assert
or check-type
, which indeed supply such loops.)
(do ()
((known-wordp word) word)
(cerror "You will be prompted for a replacement word."
"~S is an unknown word (possibly misspelled)."
word)
(format *query-io* "~&New word: ")
(setq word (read *query-io*)))
In complex cases where the error-format-string uses some of
the args and the continue-format-string uses others,
it may be necessary to use the format
directives
~*
and ~@*
to skip over unwanted arguments in
one or both of the format control strings.
Compatibility note: The Lisp Machine Lisp function
fsignal
is similar to this, but returns
:no-action
rather than nil
, and fails to
distinguish between the error message and the continue message.
[Function]
warn
format-string
&rest
args
warn
prints an error message but normally doesn’t go into
the debugger. (However, this may be controlled by the variable
*break-on-warnings*
.)
X3J13 voted in March 1989 (BREAK-ON-WARNINGS-OBSOLETE) to remove
*break-on-warnings*
from the language. See
*break-on-signals*
.
warn
returns nil
.
This function would be just the same as format
with the
output directed to the stream in error-output
, except that
warn
may perform various implementation-dependent
formatting and other actions. For example, an implementation of
warn
should take care of advancing to a fresh line before
and after the error message and perhaps supplying the name of the
function that called warn
.
Compatibility note: The Lisp Machine Lisp function
compiler:warn
is an approximate equivalent to this.
X3J13 voted in June 1988 (CONDITION-SYSTEM) to adopt a proposal for a
Common Lisp Condition System. This proposal modifies the definition of
warn
to specify its interaction with the condition system.
See section 29.4.9.
[Variable]
*break-on-warnings*
If *break-on-warnings*
is not nil
, then the
function warn
behaves like break
. It prints
its message and then goes to the debugger or break loop. Continuing
causes warn
to return nil
. This flag is
intended primarily for use when the user is debugging programs that
issue warnings; in ``production’’ use, the value of
*break-on-warnings*
should be nil
.
X3J13 voted in March 1989 (BREAK-ON-WARNINGS-OBSOLETE) to remove
*break-on-warnings*
from the language. See
*break-on-signals*
.
[Function]
break &optional
format-string
&rest
args
break
prints the message and goes directly into the
debugger, without allowing any possibility of interception by programmed
error-handling facilities. (Right now, there aren’t any error-handling
facilities defined in Common Lisp, but there might be in particular
implementations, and there will be some defined by Common Lisp in the
future.) When continued, break
returns nil
. It
is permissible to call break
with no arguments; a suitable
default message will be provided.
break
is presumed to be used as a way of inserting
temporary debugging ``breakpoints’’ in a program, not as a way of
signaling errors; it is expected that continuing from a
break
will not trigger any unusual recovery action. For
this reason, break
does not take the additional
format
control string argument that cerror
takes. This and the lack of any possibility of interception by
programmed error handling are the only program-visible differences
between break
and cerror
. The interactive
debugger may choose to display them differently; for instance, a
cerror
message might be prefixed with the herald
``Error:
’’ and a break
message with
``Break:
’‘. This depends on the user-interface style of the
particular implementation. A particular implementation may choose,
according to its own style and needs, when break
is called
to go into a debugger different from the one used for handling errors.
For example, it might go into an ordinary read-eval-print loop identical
to the top-level one except for the provision of a ``continue’’ command
that causes break
to return nil
.
Compatibility note: In MacLisp, break
is a special form (FEXPR) that takes two optional arguments. The first
is a symbol (it would be a string if MacLisp had strings), which is not
evaluated. The second is evaluated to produce a truth value specifying
whether break
should break (true) or return immediately
(false). In Common Lisp one makes a call to break
conditional by putting it inside a conditional form such as
when
or unless
.
X3J13 voted in June 1988 (CONDITION-SYSTEM) to adopt a proposal for a
Common Lisp Condition System. This proposal modifies the definition of
break
to specify its interaction with the condition system.
See section 29.4.11.
Next: Specialized
Error-Signaling Forms Up: Errors Previous: Errors
AI.Repository@cs.cmu.edu