.c	Friday  Dec 2,1983  1:41  LQ+4D.19H.48M.42S.  -*- Bolio -*-

.chapter "Errors"

Errors in lan{nil} work by signalling term_i{error conditions}
using fun_i{signal}.  The specifics of this are going to be changing
in various ways;  however, the basic interfaces for "creating" errors
can hopefully be kept static, at least insofar as the functions can be
made to accept and interpret arguments upwards-compatibly.

.defun cerror proceedable restartable condition-name format-string args
This is what needs to be used to signal correctable errors.  For an
error to be correctable (in the current scheme), one uses 3cerror*
and gives a non-null 2proceedable* argument.  The
2restartable* argument has to do with saying that the error
can be "restarted" (i.e., something gets tried over again) by throwing
to a tag with name 3error-restart*;  this is hardly, if ever,
used, and will probably be obsolete quite soon.

2condition-name* is the name of the condition being signalled;  it
is typically, although not necessarily, a keyword.

2format-string* is a string suitable as an argument to
3format* with extra arguments of 2args*;  that is how the
error message is produced.  There are, however, conventions on what
particular arguments mean for particular conditions;  some of them are
described below.

At some point, the error system and how errors (and non-error
conditions) are signalled will all change.  It should be the case,
however, that vanilla uses of 3cerror*, especially those with the
error conditions listed below, will continue to work.
.end_defun

Here are some of the interesting and well-formed error conditions
defined in lan{nil} right now, and the arguments they expect.  (Note
that extra arguments may always be given.)
.table 3 250 250
.item :wrong-type-argument 2type-name* 2losing-object*
This has to be the most common condition used in lan{nil}.
2type-name* is the name of the type of object which was expected,
such as 3number*, and 2losing-object* is the object.  (The
2type-name* is not currently used for anything, and lots of code
just puts a fairly random symbol there.)  The
value returned is used in place of the value of the wrong type.  For
example, a subroutine which arg-checks for 3fixnum*:
.lisp
(defun si:require-fixnum (x)
  (do () ((fixnump x) x)
     (setq x (cerror t nil :wrong-type-argument
		     "~*~S is not a fixnum"
		     'fixnum x))))
.end_lisp
Wrong-type-argument checks are so common that it is better to
subroutinize or macroify them rather than writing out loops.  See, for
instance, mac_i{check-arg} ((check-arg-fun)).
.item :unbound-variable 2variable*
2variable* was not bound.  Returning a value uses that as the
variable instead.
.item :undefined-function 2name*
2name* is not defined as a function.  Returning a value uses that
as the function name instead.
.item :wrong-number-of-arguments 2random*
This is handled spastically right now.  will probably be superceded by
something else.  At least when called from compiled code, returning a
value causes that value to be returned as if from the losing call.
.item :invalid-form 2form*
2form* was not meaningful to 3eval*.  The return value is
evaluated in place of the bad form.
.item :io-lossage 2description* 2form*
Sort of a catch-all for random I/O errors.  2description* is a
string describing the error, and 2form* is the form which produced
it;  for instance
.lisp
(delete-file "[foo]bar.baz")
.end_lisp
might signal a 3:io-lossage* error with a 2description* of the
string
.lisp
"%RMS-E-DNF, directory not found"
.end_lisp
and a 2form* like
.lisp
(delete-file #<pathname "sys$sysdevice:[foo]bar.baz">)
.end_lisp

.item :symbolic-constant-update 2symbol 1&optional* value old-value*
An attempt to update a value cell which is supposed to be constant was
detected.  In principle, this can happen to any type of value cell
(i.e., special or lexical value or function cells), although in
practice only special value cells are created in this manner.  The
text of the error message gives the context (i.e., 3makunbound*,
3set*, variable binding, etc.).  The 2value* and
2old-value* are given when convenient for the code generating the
error to do so.

Continuing from this error continues without having performed the
3set*, binding, 3makunbound*, or whatever.  The revised error
system will probably offer a menu of which this is one option, and
doing the operation is another.

.item :symbolic-constant-redefinition 2symbol old-value new-value*
This is somewhat similar to 3:symbolic-constant-update*, but is
signalled by (the primitive used by) 3defconstant*
((defconstant-fun)) when the symbol being defined as a constant has
a value already which differs from the one being assigned.  Returning
from the error ignores the value returned and proceeds to modify the
value of the symbol.
.end_table

