[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The MIT Scheme error system provides a uniform mechanism for the signalling of errors and other exceptional conditions. The simplest and most generally useful procedures in the error system are:
error
warn
ignore-errors
ignore-errors
.
More demanding applications require more powerful facilities. To give a concrete example, suppose you want floating-point division to return a very large number whenever the denominator is zero. This behavior can be implemented using the error system.
The Scheme arithmetic system can signal many different kinds of errors, including floating-point divide by zero. In our example, we would like to handle this particular condition specially, allowing the system to handle other arithmetic errors in its usual way.
The error system supports this kind of application by providing mechanisms for distinguishing different types of error conditions and for specifying where control should be transferred should a given condition arise. In this example, there is a specific object that represents the "floating-point divide by zero" condition type, and it is possible to dynamically specify an arbitrary Scheme procedure to be executed when a condition of that type is signalled. This procedure then finds the stack frame containing the call to the division operator, and returns the appropriate value from that frame.
Another useful kind of behavior is the ability to specify uniform handling for related classes of conditions. For example, it might be desirable, when opening a file for input, to gracefully handle a variety of different conditions associated with the file system. One such condition might be that the file does not exist, in which case the program will try some other action, perhaps opening a different file instead. Another related condition is that the file exists, but is read protected, so it cannot be opened for input. If these or any other related conditions occur, the program would like to skip this operation and move on to something else.
At the same time, errors unrelated to the file system should be treated in
their usual way. For example, calling car
on the argument 3
should signal an error. Or perhaps the name given for the file is
syntactically incorrect, a condition that probably wants to be handled
differently from the case of the file not existing.
To facilitate the handling of classes of conditions, the error system taxonomically organizes all condition types. The types are related to one another by taxonomical links, which specify that one type is a "kind of" another type. If two types are linked this way, one is considered to be a specialization of the other; or vice-versa, the second is a generalization of the first. In our example, all of the errors associated with opening an input file would be specializations of the condition type "cannot open input file".
The taxonomy of condition types permits any condition type to have no
more than one immediate generalization. Thus, the condition types form
a forest (set of trees). While users can create new trees, the standard
taxonomy (see section 16.7 Condition-Type Taxonomy) is rooted at
condition-type:serious-condition
, condition-type:warning
,
condition-type:simple-condition
, and
condition-type:breakpoint
; users are encouraged to add new
subtypes to these condition types rather than create new trees in the
forest.
To summarize, the error system provides facilities for the following tasks. The sections that follow will describe these facilities in more detail.
error
. The signal-condition
procedure provides the
most general signalling mechanism.
bind-condition-handler
procedure. Individual handlers have
complete control over the handling of a condition, and additionally may
decide not to handle a particular condition, passing it on to previously
bound handlers.
with-restart
procedure provides a means for
condition-signalling code to communicate to condition-handling code what
must be done to proceed past the condition. Handlers can examine the
restarts in effect when a condition was signalled, allowing a structured
way to continue an interrupted computation.
16.1 Condition Signalling 16.2 Error Messages 16.3 Condition Handling 16.4 Restarts 16.5 Condition Instances 16.6 Condition Types 16.7 Condition-Type Taxonomy
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Once a condition instance has been created using make-condition
(or any condition constructor), it can be signalled. The act of
signalling a condition is separated from the act of creating the
condition to allow more flexibility in how conditions are handled. For
example, a condition instance could be returned as the value of a
procedure, indicating that something unusual has happened, to allow the
caller to clean up some state. The caller could then signal the
condition once it is ready.
A more important reason for having a separate condition-signalling mechanism is that it allows resignalling. When a signalled condition has been caught by a particular handler, and the handler decides that it doesn't want to process that particular condition, it can signal the condition again. This is one way to allow other handlers to get a chance to see the condition.
warn
is more appropriate).
error
signals a condition (using signal-condition
), and if
no handler for that condition alters the flow of control (by invoking a
restart, for example) it calls the procedure
standard-error-handler
, which normally prints an error message
and stops the computation, entering an error REPL. Under normal
circumstances error
will not return a value (although an
interactive debugger can be used to force this to occur).
Precisely what condition is signalled depends on the first argument to
error
. If reason is a condition, then that condition is
signalled and the arguments are ignored. If reason is a
condition type, then a new instance of this type is generated and
signalled; the arguments are used to generate the values of the
fields for this condition type (they are passed as the field-plist
argument to make-condition
). In the most common case, however,
reason is neither a condition nor a condition type, but rather a
string or symbol. In this case a condition of type
condition-type:simple-error
is created with the message
field containing the reason and the irritants field
containing the arguments.
warn
rather than
error
. As with error
, warn
first calls
signal-condition
; the condition that is signalled is chosen
exactly as in error
except that a condition of type
condition-type:simple-warning
is signalled if reason is
neither a condition nor a condition type. If the condition is not
handled, warn
calls the procedure
standard-warning-handler
, which normally prints a warning message
and continues the computation by returning from warn
.
warn
establishes a restart named muffle-warning
before
calling signal-condition
. This allows a signal handler to
prevent the generation of the warning message by calling
muffle-warning
. The value of a call to warn
is
unspecified.
signal-condition
depends on the condition
type of which condition is an instance, the condition types set by
break-on-signals
, and the handlers established by
bind-condition-handler
and bind-default-condition-handler
.
If the condition is an instance of a type that is a specialization
of any of the types specified by break-on-signals
, then a
breakpoint REPL is initiated. Otherwise (or when that REPL
returns), the handlers established by bind-condition-handler
are
checked, most recent first. Each applicable handler is invoked, and the
search for a handler continues if the handler returns normally. If all
applicable handlers return, then the applicable handlers established by
bind-default-condition-handler
are checked, again most recent
first. Finally, if no handlers apply (or all return in a normal
manner), signal-condition
returns an unspecified value.
Note: unlike many other systems, the MIT Scheme runtime library
does not establish handlers of any kind. (However, the Edwin
text editor uses condition handlers extensively.) Thus, calls to
signal-condition
will return to the caller unless there are user
supplied condition handlers, as the following example shows:
(signal-condition (make-condition condition-type:error (call-with-current-continuation (lambda (x) x)) '() ; no restarts '())) ; no fields => unspecified |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
By convention, error messages (and in general, the reports generated by
write-condition-report
) should consist of one or more complete
sentences. The usual rules for sentences should be followed: the first
word of the sentence should be capitalized, and the sentence should be
terminated by a period. The message should not contain extraneous
whitespace such as line breaks or indentation.
The error system provides a simple formatting language that allows the programmer to have some control over the printing of error messages. This formatting language will probably be redesigned in a future release.
Error messages typically consist of a string describing the error,
followed by some irritant objects. The string is printed using
display
, and the irritants are printed using write
,
typically with a space between each irritant. To allow simple
formatting, we introduce a noise object, printed using
display
. The irritant list may contain ordinary objects
interspersed with noise objects. Each noise object is printed using
display
, with no extra whitespace, while each normal object is
printed using write
, prefixed by a single space character.
Here is an example:
(define (error-within-procedure message irritant procedure) (error message irritant (error-irritant/noise "within procedure") procedure (error-irritant/noise "."))) |
This would format as follows:
(error-within-procedure "Bad widget" 'widget-32 'invert-widget) error--> Bad widget widget-32 within procedure invert-widget. |
Here are the operations supporting error messages:
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The occurrence of a condition is signalled using
signal-condition
. signal-condition
attempts to locate and
invoke a condition handler that is prepared to deal with the type
of condition that has occurred. A condition handler is a procedure of
one parameter, the condition that is being signalled. A procedure is
installed as a condition handler by calling
bind-condition-handler
(to establish a handler that is in effect
only while a particular thunk is executing) or
bind-default-condition-handler
(to establish a handler that is in
effect permanently). As implied by the name, handlers created by
bind-default-condition-handler
are invoked only after all other
applicable handlers have been invoked.
A handler may process a signal in any way it deems appropriate, but the common patterns are:
signal-condition
.
signal-condition
with either
the same condition or a newly created one. In order to support this,
signal-condition
runs handler in such a way that a
subsequent call to signal-condition
sees only the handlers that
were established prior to this one.
As an aid to debugging condition handlers, Scheme maintains a set of
condition types that will cause an interactive breakpoint to occur prior
to normal condition signalling. That is, signal-condition
creates a new REPL prior to its normal operation when its argument
is a condition that is a specialization of any of these types. The
procedure break-on-signals
establishes this set of condition
types.
condition-type:error
(including those produced by calls to error
) and immediately
terminates the execution of thunk and returns from the call to
ignore-errors
with the signalled condition as its value. If
thunk returns normally, its value is returned from
ignore-errors
.
Notice that ignore-errors
does not "turn off signalling" or
condition handling. Condition handling takes place in the normal manner
but conditions specialized from condition-type:error
are trapped
rather than propogated as they would be by default.
signal-condition
for
a description of the mechanism used to invoke handlers.
By special extension, if condition-types is the empty list then the handler is called for all conditions.
signal-condition
for a description of the
mechanism used to invoke handlers.
By special extension, if condition-types is the empty list then the handler is called for all conditions.
signal-condition
to create an interactive REPL
before it signals a condition that is a specialization of any of the
types in the list of condition-types. This can be extremely
helpful when trying to debug code that uses custom condition handlers.
In order to create a REPL when any condition type is
signalled it is best to actually put a breakpoint on entry to
signal-condition
.
error
after it calls
signal-condition
. Normally creates creates a new REPL with
the prompt "error>"
(but see standard-error-hook
). In
order to simulate the effect of calling error
, code may call
signal-condition
directly and then call
standard-error-handler
if signal-condition
returns.
standard-error-handler
, and hence error
. It is intended
to be bound with fluid-let
and is normally #f
. It may be
changed to a procedure of one argument and will then be invoked (with
standard-error-hook
rebound to #f
) by
standard-error-handler
just prior to starting the error
REPL. It is passed one argument, the condition being signalled.
warn
after it calls
signal-condition
. The normal behavior of
standard-warning-handler
is to print a message (but see
standard-warning-hook
). More precisely, the message is printed
to the port returned by notification-output-port
. The message is
formed by first printing the string "Warning: "
to this port, and
then calling write-condition-report
on condition and the port.
In order to simulate the effect of calling warn
, code may call
signal-condition
directly and then call
standard-warning-handler
if signal-condition
returns.
(This is not sufficient to implement the muffle-warning
protocol,
however. For that purpose an explicit restart must be provided.)
standard-warning-handler
, and hence warn
. It is intended
to be bound with fluid-let
and is normally #f
. It may be
changed to a procedure of one argument and will then be invoked (with
standard-warning-hook
rebound to #f
) by
standard-warning-handler
in lieu of writing the warning message.
It is passed one argument, the condition being signalled.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The Scheme error system provides a mechanism, known as restarts,
that helps coordinate condition-signalling code with condition-handling
code. A module of code that detects and signals conditions can provide
procedures (using with-simple-restart
or with-restart
) to
be invoked by handlers that wish to continue, abort, or restart the
computation. These procedures, called restart effectors, are
encapsulated in restart objects.
When a condition object is created, it contains a set of restart
objects, each of which contains a restart effector. Condition handlers
can inspect the condition they are handling (using find-restart
to find restarts by name, or condition/restarts
to see the entire
set), and they can invoke the associated effectors (using
invoke-restart
or invoke-restart-interactively
).
Effectors can take arguments, and these may be computed directly by the
condition-handling code or by gathering them interactively from the
user.
The names of restarts can be chosen arbitrarily, but the choice of name is significant. These names are used to coordinate between the signalling code (which supplies names for restarts) and the handling code (which typically chooses a restart effector by the name of its restart). Thus, the names specify the restart protocol implemented by the signalling code and invoked by the handling code. The protocol indicates the number of arguments required by the effector code as well as the semantics of the arguments.
Scheme provides a conventional set of names (hence, protocols) for
common use. By choosing the names of restarts from this set, signalling
code can indicate that it is able to perform a small set of fairly
common actions (abort
, continue
, muffle-warning
,
retry
, store-value
, use-value
). In turn, simple
condition-handling code can look for the kind of action it wishes to
perform and simply invoke it by name. All of Scheme's conventional
names are symbols, although in general restart names are not restricted
to any particular data type. In addition, the object #f
is
reserved to indicate the "not for automated use" protocol: these
restarts should be activated only under human control.
Restarts themselves are first-class objects. They encapsulate their
name, a procedure (known as the effector) to be executed if they
are invoked, and a thunk (known as the reporter) that can be
invoked to display a description of the restart (used, for example, by
the interactive debugger). Invoking a restart is an indication that a
handler has chosen to accept control for a condition; as a consequence,
the effector of the restart should not return, since this would
indicate that the handler declined to handle the condition. Thus, the
effector should call a continuation captured before the
condition-signalling process began. The most common pattern of usage by
signalling code is encapsulated in with-simple-restart
.
Within this chapter, a parameter named restarts will accept any of the following values:
condition/restarts
is called on the
condition, and the resulting list of restarts is used in place of the
condition.
bound-restarts
. The procedure bound-restarts
is called (with no arguments), and the resulting list of restarts is
used in place of the symbol.
bound-restarts
.
16.4.1 Establishing Restart Code 16.4.2 Invoking Standard Restart Code 16.4.3 Finding and Invoking General Restart Code 16.4.4 The Named Restart Abstraction
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
If the restart created by with-simple-restart
is invoked it
simply aborts the computation in progress by returning an unspecified
value from the call to with-simple-restart
. Otherwise
with-simple-restart
returns the value computed by thunk.
(with-simple-restart 'george "This restart is named george."
(lambda () 3)) => 3
(with-simple-restart 'george "This restart is named george."
(lambda ()
(invoke-restart (find-restart 'george)))) => |
invoke-restart
. Interactor
specifies the arguments that are to be passed to effector when it
is invoked interactively; it may be either a procedure of no arguments,
or #f
. If interactor is #f
, this restart is not
meant to be invoked interactively.
The value returned by with-restart
is the value returned by
thunk. Should the restart be invoked by a condition handler,
however, the effector will not return back to the handler that
invoked it. Instead, the effector should call a continuation
created before the condition-signalling process began, and
with-restart
will therefore not return in the normal manner.
(define (by-george! thunk) ; This code handles conditions that arise while executing thunk ; by invoking the GEORGE restart, passing 1 and 2 to the restart's ; effector code. (bind-condition-handler '() ; All conditions (lambda (condition) (invoke-restart (find-restart 'george) 1 2)) thunk)) (define (can-george! thunk) ; This code provides a way of handling errors: the GEORGE restart. ; In order to GEORGE you must supply two values. (lambda () (call-with-current-continuation (lambda (kappa) (with-restart 'george ; Name "This restart is named george." ; Reporter (lambda (a b) ; Effector (kappa (list 'george a b))) values ; Interactor thunk))))) ; Thunk (by-george! (can-george! (lambda () -3)) => -3 (by-george! (can-george! (lambda () (car 'x)))) => (george 1 2) |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Scheme supports six standard protocols for restarting from a condition, each encapsulated using a named restart (for use by condition-signalling code) and a simple procedure (for use by condition-handling code). Unless otherwise specified, if one of these procedures is unable to find its corresponding restart, it returns immediately with an unspecified value.
Each of these procedures accepts an optional argument restarts, which is described above in 16.4 Restarts.
abort
. The
corresponding effector takes no arguments and abandons the current line
of computation. This is the restart provided by Scheme's REPL.
If there is no restart named abort
, this procedure signals an
error of type condition-type:no-such-restart
.
continue
. The corresponding effector takes no arguments and
continues the computation beyond the point at which the condition was
signalled.
muffle-warning
. The corresponding effector takes no arguments
and continues the computation beyond the point at which any warning
message resulting from the condition would be presented to the user.
The procedure warn
establishes a muffle-warning
restart
for this purpose.
If there is no restart named muffle-warning
, this procedure
signals an error of type condition-type:no-such-restart
.
retry
.
The corresponding effector takes no arguments and simply retries the
same computation that triggered the condition. The condition may
reoccur, of course, if the root cause has not been eliminated. The code
that signals a "file does not exist" error can be expected to supply a
retry
restart. The restart would be invoked after first creating
the missing file, since the computation is then likely to succeed if it
is simply retried.
store-value
, after first storing new-value. The
corresponding effector takes one argument, new-value, and stores
it away in a restart-dependent location, then retries the same
computation that triggered the condition. The condition may reoccur, of
course, if the root cause has not been eliminated. The code that
signals an "unassigned variable" error can be expected to supply a
store-value
restart; this would store the value in the variable
and continue the computation.
use-value
,
but substituting new-value for a value that previously caused a
failure. The corresponding effector takes one argument,
new-value, and retries the same computation that triggered the
condition with the new value substituted for the failing value. The
condition may reoccur, of course, if the new value also induces the
condition.
The code that signals an "unassigned variable" error can be expected
to supply a use-value
restart; this would simply continue the
computation with new-value instead of the value of the variable.
Contrast this with the retry
and store-value
restarts. If
the retry
restart is used it will fail because the variable still
has no value. The store-value
restart could be used, but it
would alter the value of the variable, so that future references to the
variable would not be detected.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Restarts are a general mechanism for establishing a protocol between
condition-signalling and condition-handling code. The Scheme error
system provides "packaging" for a number of common protocols. It also
provides lower-level hooks that are intended for implementing customized
protocols. The mechanism used by signalling code (with-restart
and with-simple-restart
) is used for both purposes.
Four additional operations are provided for the use of
condition-handling code. Two operations (bound-restarts
and
find-restart
) allow condition-handling code to locate active
restarts. The other two operations (invoke-restart
and
invoke-restart-interactively
) allow restart effectors to be
invoked once the restart object has been located.
In addition, there is a data abstraction that provides access to the information encapsulated in restart objects.
bound-restarts
should be used with caution by
condition-handling code, since it reveals all restarts that are active
at the time it is called, rather than at the time the condition was
signalled. It is useful, however, for collecting the list of restarts
for inclusion in newly generated condition objects or for inspecting the
current state of the system.
find-restart
is usually passed the name of a particular restart
and the condition object that has been signalled. In this way
the handler finds only restarts that were available when the condition
was created (usually the same as when it was signalled). If
restarts is omitted, the currently active restarts would be used,
and these often include restarts added after the condition ocurred.
invoke-restart
is intended for
use by condition-handling code that understands the protocol implemented
by restart, and can therefore calculate and pass an appropriate
set of arguments.
If a condition handler needs to interact with a user to gather the
arguments for an effector (e.g. if it does not understand the protocol
implemented by restart) invoke-restart-interactively
should
be used instead of invoke-restart
.
invoke-restart-interactively
is intended for calling interactive
restarts (those for which restart/interactor
is not #f
).
For convenience, invoke-restart-interactively
will call the
restart's effector with no arguments if the restart has no interactor;
this behavior may change in the future.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A restart object is very simple, since it encapsulates only a name, effector, interactor, and description.
#f
if and only if object is not a restart.
#f
for its predefined names, programs
may use arbitrary objects (name equivalence is tested using eq?
).
invoke-restart
and
invoke-restart-interactively
capture the most common invocation
patterns.
#f
. Normally this
procedure is not used since invoke-restart-interactively
captures
the most common usage. Thus restart/interactor
is most useful as
a predicate to determine if restart is intended to be invoked
interactively.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A condition, in addition to the information associated with its type, usually contains other information that is not shared with other conditions of the same type. For example, the condition type associated with "unbound variable" errors does not specify the name of the variable that was unbound. The additional information is captured in a condition object, also called a condition instance.
In addition to information that is specific to a given type of condition (such as the variable name for "unbound variable" conditions), every condition instance also contains a continuation that encapsulates the state of the computation in which the condition occurred. This continuation is used for analyzing the computation to learn more about the context in which the condition occurred. It is not intended to provide a mechanism for continuing the computation; that mechanism is provided by restarts.
16.5.1 Generating Operations on Conditions 16.5.2 Condition Abstraction 16.5.3 Simple Operations on Condition Instances
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Scheme provides four procedures that take a condition type as input and
produce operations on the corresponding condition object. These are
reminiscent of the operations on record types that produce record
operators (see section 10.4 Records). Given a condition type it is possible to
generate: a constructor for instances of the type (using
condition-constructor
); an accessor to extract the contents of a
field in instances of the type (using condition-accessor
); a
predicate to test for instances of the type (using
condition-predicate
); and a procedure to create and signal an
instance of the type (using condition-signaller
).
Notice that the creation of a condition object is distinct from signalling an occurrence of the condition. Condition objects are first-class; they may be created and never signalled, or they may be signalled more than once. Further notice that there are no procedures for modifying conditions; once created, a condition cannot be altered.
condition-constructor
has
signature
(lambda (continuation restarts . field-values) ...) |
where the field-names correspond to the field-values. The
constructor argument restarts is described in 16.4 Restarts.
Conditions created by the constructor procedure have #f
for the
values of all fields other than those specified by field-names.
For example, the following procedure make-simple-warning
constructs a condition of type condition-type:simple-warning
given a continuation (where the condition occurred), a description of
the restarts to be made available, a warning message, and a list of
irritants that caused the warning:
(define make-simple-warning (condition-constructor condition-type:simple-warning '(message irritants))) |
condition-accessor
signals
error:bad-range-argument
if the field-name isn't one of the
named fields of condition-type; the returned procedure will signal
error:wrong-type-argument
if passed an object other than a
condition of type condition-type or one of its specializations.
If it is known in advance that a particular field of a condition will be
accessed repeatedly it is worth constructing an accessor for the field
using condition-accessor
rather than using the (possibly more
convenient, but slower) access-condition
procedure.
There are several standard procedures that are conventionally used for
default-handler. If condition-type is a specialization of
condition-type:error
, default-handler should be the
procedure
standard-error-handler
. If condition-type is a
specialization of condition-type:warning
, default-handler
should be the procedure standard-warning-handler
. If
condition-type is a specialization of
condition-type:breakpoint
, default-handler should be the
procedure standard-breakpoint-handler
.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The condition data type is abstracted through a predicate
condition?
and a set of accessor procedures.
#f
if and only if object is not a condition.
#t
if the condition is an instance of condition
type condition-type:error
or a specialization of it, #f
otherwise.
condition/report-string
.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The simple procedures described in this section are built on top of the more detailed abstraction of condition objects described above. While these procedures are sometimes easier to use, they are often less efficient.
(condition-type/field-names condition-type)
. It is used to
provide values for fields in the condition object; fields with no value
specified are set to #f
. Once a condition object has been
created there is no way to alter the values of these fields.
(condition-type/field-names (condition/type condition))
.
access-condition
looks up the field-name at runtime, so it
is more efficient to use condition-accessor
to create an access
function if the same field is to be extracted from several instances of
the same condition type.
write-condition-report
on condition
and a string output port, and returning the output collected by the port
as a string.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Each condition has a condition type object associated with it. These objects are used as a means of focusing on related classes of conditions, first by concentrating all of the information about a specific class of condition in a single place, and second by specifying an inheritance relationship between types. This inheritance relationship forms the taxonomic structure of the condition hierarchy (see section 16.7 Condition-Type Taxonomy).
The following procedures consititute the abstraction for condition types.
#f
). For
debugging purposes, the condition type has a name, and instances
of this type contain storage for the fields specified by
field-names (a list of symbols) in addition to the fields common
to all conditions (type, continuation and restarts).
Reporter is used to produce a description of a particular
condition of this type. It may be a string describing the condition, a
procedure of arity two (the first argument will be a condition of this
type and the second a port) that will write
the message to the
given port, or #f
to specify that the reporter should be taken
from the condition type generalization (or produce an
"undocumented condition of type ..." message if generalization
is #f
). The conventions used to form descriptions are spelled
out in 16.2 Error Messages.
#t
if the condition-type is
condition-type:error
or a specialization of it, #f
otherwise.
condition-type/field-names
of the generalization of this
condition-type.
#f
if and only if object is not a condition type.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The MIT Scheme error system provides a rich set of predefined condition
types. These are organized into a forest through taxonomic links
providing the relationships for "specializes" and "generalizes".
The chart appearing below shows these relationships by indenting all the
specializations of a given type relative to the type. Note that the
variables that are bound to these condition types are prefixed by
`condition-type:'; for example, the type appearing in the following
table as `simple-error' is stored in the variable
condition-type:simple-error
. Users are encouraged to add new
condition types by creating specializations of existing ones.
Following the chart are detailed descriptions of the predefined condition types. Some of these types are marked as abstract types. Abstract types are not intended to be used directly as the type of a condition; they are to be used as generalizations of other types, and for binding condition handlers. Types that are not marked as abstract are concrete; they are intended to be explicitly used as a condition's type.
serious-condition error simple-error illegal-datum wrong-type-datum wrong-type-argument wrong-number-of-arguments datum-out-of-range bad-range-argument inapplicable-object file-error file-operation-error derived-file-error port-error derived-port-error variable-error unbound-variable unassigned-variable arithmetic-error divide-by-zero floating-point-overflow floating-point-underflow control-error no-such-restart not-loading primitive-procedure-error system-call-error warning simple-warning simple-condition breakpoint |
error
procedure when its
first argument is not a condition or condition type. The fields
message and irritants are taken directly from the arguments
to error
; message contains an object (usually a string) and
irritants contains a list of objects. The reporter for this type
uses format-error-message
to generate its output from
message and irritants.
(error:wrong-type-datum 3.4 "integer") error--> ;The object 3.4 is not an integer. ;To continue, call RESTART with an option number: ; (RESTART 1) => Return to read-eval-print level 1. |
condition-type:wrong-type-datum
. The datum and type
fields of the condition are filled in from the corresponding arguments
to the procedure.
#f
), the type field contains a
string describing the type that was expected, and the datum field
contains the offending argument.
(+ 'a 3) error--> ;The object a, passed as the first argument to integer-add, ; is not the correct type. ;To continue, call RESTART with an option number: ; (RESTART 2) => Specify an argument to use in its place. ; (RESTART 1) => Return to read-eval-print level 1. (list-copy 3) ;The object 3, passed as an argument to list-copy, is not a list. ;To continue, call RESTART with an option number: ; (RESTART 1) => Return to read-eval-print level 1. |
condition-type:wrong-type-argument
. The datum, type
and operator fields of the condition are filled in from the
corresponding arguments to the procedure; the operand field of the
condition is set to #f
.
(car 3 4) error--> ;The procedure car has been called with 2 arguments; ; it requires exactly 1 argument. ;To continue, call RESTART with an option number: ; (RESTART 1) => Return to read-eval-print level 1. |
condition-type:wrong-number-of-arguments
. The datum,
type and operands fields of the condition are filled in from
the corresponding arguments to the procedure.
(error:datum-out-of-range 3) error--> ;The object 3 is not in the correct range. ;To continue, call RESTART with an option number: ; (RESTART 1) => Return to read-eval-print level 1. |
condition-type:datum-out-of-range
. The datum field of the
condition is filled in from the corresponding argument to the procedure.
#f
), and the
datum field is the offending argument.
(string-ref "abc" 3) error--> ;The object 3, passed as the second argument to string-ref, ; is not in the correct range. ;To continue, call RESTART with an option number: ; (RESTART 2) => Specify an argument to use in its place. ; (RESTART 1) => Return to read-eval-print level 1. |
condition-type:bad-range-argument
. The datum and
operator fields of the condition are filled in from the
corresponding arguments to the procedure; the operand field of the
condition is set to #f
.
(3 4) error--> ;The object 3 is not applicable. ;To continue, call RESTART with an option number: ; (RESTART 2) => Specify a procedure to use in its place. ; (RESTART 1) => Return to read-eval-print level 1. |
filename "/zu/cph/tmp/no-such-file" verb "delete" noun "file" reason "no such file or directory" operator file-remove operands ("/zu/cph/tmp/no-such-file") |
and would generate a message like this:
(delete-file "/zu/cph/tmp/no-such-file") error--> ;Unable to delete file "/zu/cph/tmp/no-such-file" because: ; No such file or directory. ;To continue, call RESTART with an option number: ; (RESTART 3) => Try to delete the same file again. ; (RESTART 2) => Try to delete a different file. ; (RESTART 1) => Return to read-eval-print level 1. |
condition-type:file-operation-error
. The fields of the condition
are filled in from the corresponding arguments to the procedure.
condition-type:system-call-error
.
condition-type:derived-file-error
. The filename and
condition fields of the condition are filled in from the
corresponding arguments to the procedure.
condition-type:system-call-error
.
condition-type:derived-port-error
. The port and
condition fields of the condition are filled in from the
corresponding arguments to the procedure.
foo error--> ;Unbound variable: foo ;To continue, call RESTART with an option number: ; (RESTART 3) => Specify a value to use instead of foo. ; (RESTART 2) => Define foo to a given value. ; (RESTART 1) => Return to read-eval-print level 1. |
foo error--> ;Unassigned variable: foo ;To continue, call RESTART with an option number: ; (RESTART 3) => Specify a value to use instead of foo. ; (RESTART 2) => Set foo to a given value. ; (RESTART 1) => Return to read-eval-print level 1. |
(/ 1 0) ;Division by zero signalled by /. ;To continue, call RESTART with an option number: ; (RESTART 1) => Return to read-eval-print level 1. |
condition-type:divide-by-zero
. The operator and
operands fields of the condition are filled in from the
corresponding arguments to the procedure.
condition-type:file-operation-error
. The operator field
contains the procedure that implements the operation (or a symbol naming
the procedure), and the operands field contains a list of the
arguments that were passed to the procedure. The system-call and
error-type fields contain symbols that describe the specific
system call that was being made and the error that occurred,
respectively; these symbols are completely operating-system dependent.
muffle-warning
. The name field contains the name that was
being searched for.
(muffle-warning) error--> ;The restart named muffle-warning is not bound. ;To continue, call RESTART with an option number: ; (RESTART 1) => Return to read-eval-print level 1. |
condition-type:no-such-restart
. The name field of the
condition is filled in from the corresponding argument to the procedure.
current-load-pathname
is called from somewhere other than inside
a file being loaded.
(current-load-pathname) error--> ;No file being loaded. ;To continue, call RESTART with an option number: ; (RESTART 1) => Return to read-eval-print level 1. |
warn
procedure. The
fields message and irritants are taken directly from the
arguments to warn
; message contains an object (usually a
string) and irritants contains a list of objects. The reporter
for this type uses format-error-message
to generate its output
from message and irritants.
format-error-message
to generate its
output from message and irritants.
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |