4.1cBSD/usr/src/ucb/lisp/lisplib/manual/ch10.r








                        CCCCHHHHAAAAPPPPTTTTEEEERRRR  11110000


                     EEEExxxxcccceeeeppppttttiiiioooonnnn HHHHaaaannnnddddlllliiiinnnngggg







11110000....1111....  EEEErrrrrrrrsssseeeetttt aaaannnndddd EEEErrrrrrrroooorrrr HHHHaaaannnnddddlllleeeerrrr FFFFuuuunnnnccccttttiiiioooonnnnssss

     FRANZ LISP allows the user to handle  in  a  number  of
ways  the errors which arise during computation.  One way is
through the use of the _e_r_r_s_e_t function.  If an error  occurs
during  the  evaluation of the _e_r_r_s_e_t's first argument, then
the locus of control will return to the  errset  which  will
return  nil  (except  in  special  cases, such as _e_r_r).  The
other method of error handling is through an  error  handler
function.  When an error occurs, the error handler is called
and is given as an argument  a  description   of  the  error
which  just occurred.  The error handler may take one of the
following actions:

(1)  it could take some drastic action like  a  _r_e_s_e_t  or  a
     _t_h_r_o_w.

(2)  it could,  assuming  that  the  error  is  continuable,
     return  to  the  function which noticed the error.  The
     error handler indicates that it wants to return a value
     from  the  error  by  returning a list whose _c_a_r is the
     value it wants to return.

(3)  it could decide not to handle the error  and  return  a
     non-list to indicate this fact.




11110000....2222....  TTTThhhheeee AAAAnnnnaaaattttoooommmmyyyy ooooffff aaaannnn eeeerrrrrrrroooorrrr

     Each error is described by a list of these items:

(1)  error type - This is a symbol which indicates the  gen-
     eral  classification of the error.  This classification
     may determine which function handles this error.

(2)  unique id - This is a fixnum unique to this error.

(3)  continuable - If this is non-nil  then  this  error  is
     continuable.   There are some who feel that every error
     should be continuable and the reason that some (in fact


EEEExxxxcccceeeeppppttttiiiioooonnnn HHHHaaaannnnddddlllliiiinnnngggg                                      11110000----1111







EEEExxxxcccceeeeppppttttiiiioooonnnn HHHHaaaannnnddddlllliiiinnnngggg                                      11110000----2222


     most)  errors  in FRANZ LISP are not continuable is due
     to the laziness of the programmers.

(4)  message string - This is a symbol whose print  name  is
     a message describing the error.

(5)  data - There may be from  zero  to  three  lisp  values
     which  help describe this particular  error.  For exam-
     ple, the unbound  variable  error  contains  one  datum
     value,  the  symbol  whose  value is unbound.  The list
     describing that error might look like:
            (ER%misc 0 t |Unbound Variable:| foobar)




11110000....3333....  EEEErrrrrrrroooorrrr hhhhaaaannnnddddlllliiiinnnngggg aaaallllggggoooorrrriiiitttthhhhmmmm

     This is the sequence of operations which is  done  when
an error occurs:

(1)  If the symbol EEEERRRR%%%%aaaallllllll has a  non  nil  value  then  this
     value  is  the name of an error handler function.  That
     function is called with a description of the error.  If
     that  function returns (and of course it may choose not
     to) and the value is a list and this error is  continu-
     able,  then  we return the _c_a_r of the list to the func-
     tion which called the error.  Presumably  the  function
     will  use  this  value  to retry the operation.  On the
     other hand, if the error handler returns  a  non  list,
     then  it has chosen not to handle this error, so  we go
     on to step (2).  Something special  happens  before  we
     call  the EEEERRRR%%%%aaaallllllll error handler which does not happen in
     any of the other cases we will describe below.  To help
     insure  that  we  don't get infinitely recursive errors
     if EEEERRRR%%%%aaaallllllll is set to a bad value, the value of EEEERRRR%%%%aaaallllllll is
     set  to  nil  before the handler is called.  Thus it is
     the responsibility of the EEEERRRR%%%%aaaallllllll handler to  `reenable'
     itself by storing its name in EEEERRRR%%%%aaaallllllll....

(2)  Next the specific error handler for the type  of  error
     which  just  occurred is called  (if one exists) to see
     if it wants to handle the  error.   The  names  of  the
     handlers for the specific types of errors are stored as
     the values of the symbols whose names  are  the  types.
     For  example  the  handler  for miscellaneous errors is
     stored as the value of EEEERRRR%%%%mmmmiiiisssscccc....  Of course, if  EEEERRRR%%%%mmmmiiiisssscccc
     has  a value of nil, then there is no error handler for
     this type of error.  Appendix B contains  list  of  all
     error  types.  The process of classifying the errors is
     not complete and thus most errors are lumped  into  the
     EEEERRRR%%%%mmmmiiiisssscccc  category.   Just  as  in  step  (1), the error
     handler function may choose not to handle the error  by


                                     Printed: March 23, 1982







EEEExxxxcccceeeeppppttttiiiioooonnnn HHHHaaaannnnddddlllliiiinnnngggg                                      11110000----3333


     returning a non-list, and then we go to step (3).

(3)  Next a check is made to see if there is an _e_r_r_s_e_t  sur-
     rounding  this error.  If so the second argument to the
     _e_r_r_s_e_t call is examined. If the second argument was not
     given  or  is non nil then the error message associated
     with this error is  printed.   Finally   the  stack  is
     popped to the context of the _e_r_r_s_e_t and then the _e_r_r_s_e_t
     returns nil.  If there was no _e_r_r_s_e_t we go to step (4).

(4)  If the symbol EEEERRRR%%%%ttttppppllll has a value then it is the name of
     an error handler which is called in a manner similar to
     that discussed above.  If it chooses not to handle  the
     error, we go to step (5).

(5)  At this point it has  been  determined  that  the  user
     doesn't want to handle this error.  Thus the error mes-
     sage is printed out and a _r_e_s_e_t is  done  to  send  the
     flow of control to the top-level.

     To summarize the error handling system: When  an  error
occurs,  you have two chances to handle it before the search
for an _e_r_r_s_e_t is done.  Then, if there  is  no  _e_r_r_s_e_t,  you
have  one  more  chance  to  handle the error before control
jumps to the top level.  Every  error handler works  in  the
same  way:  It  is  given  a  description  of  the error (as
described in the previous  section).   It  may  or  may  not
return.   If  it returns, then it returns either a list or a
non-list.  If it returns a list and the  error  is  continu-
able,  then  the _c_a_r of the list is returned to the function
which noticed the error.  Otherwise the  error  handler  has
decided  not  to  handle the error and we go on to something
else.




11110000....4444....  DDDDeeeeffffaaaauuuulllltttt aaaaiiiiddddssss

     There are two standard error handlers  which will prob-
ably  handle  the  needs of most users.  One of these is the
lisp coded function _b_r_e_a_k-_e_r_r-_h_a_n_d_l_e_r which is  the  default
value  of EEEERRRR%%%%ttttppppllll....  Thus when all other handlers have ignored
an error, _b_r_e_a_k-_e_r_r-_h_a_n_d_l_e_r will take over.  It  will  print
out  the  error  message and go into a read-eval-print loop.
The other standard error handler is _d_e_b_u_g-_e_r_r-_h_a_n_d_l_e_r.  This
handler  is  designed to be connected to EEEERRRR%%%%aaaalllllllland is useful
if your program uses _e_r_r_s_e_t and you  want  to  look  at  the
error  before it is thrown up to the _e_r_r_s_e_t.



9

9                                     Printed: March 23, 1982







EEEExxxxcccceeeeppppttttiiiioooonnnn HHHHaaaannnnddddlllliiiinnnngggg                                      11110000----4444


11110000....5555....  AAAAuuuuttttoooollllooooaaaaddddiiiinnnngggg

     When _e_v_a_l, _a_p_p_l_y or _f_u_n_c_a_l_l are told to call  an  unde-
fined  function, an EEEERRRR%%%%uuuunnnnddddeeeeffff error is signaled.  The default
handler for this error is _u_n_d_e_f-_f_u_n_c-_h_a_n_d_l_e_r.  This function
checks  the  property list of the undefined function for the
indicator autoload.  If present, the value of that indicator
should be the name of the file which contains the definition
of the undefined function.  _U_n_d_e_f-_f_u_n_c-_h_a_n_d_l_e_r will load the
file  and  check if it has defined the function which caused
the error.  If it has, the error handler will return and the
computation  will  continue  as  if the error did not occur.
This provides a way for the user to  tell  the  lisp  system
about  the  location  of commonly used functions.  The trace
package  sets  up  an  autoload   property   to   point   to
/usr/lib/lisp/trace.




11110000....6666....  IIIInnnntttteeeerrrrrrrruuuupppptttt pppprrrroooocccceeeessssssssiiiinnnngggg

     The  UNIX operating system provides one user  interrupt
character which defaults to ^C.[] The user may select a lisp
function to run when an interrupt occurs.  Since this inter-
rupt could occur at any time, and in particular could  occur
at a time when the internal stack pointers were in an incon-
sistent state,  the  processing  of  the  interrupt  may  be
delayed  until a safe time.  When the first ^C is typed, the
lisp  system  sets  a  flag  that  an  interrupt  has   been
requested.   This flag is  checked at safe places within the
interpreter and in the _q_l_i_n_k_e_r function.  If the lisp system
doesn't respond to the first ^C, another ^C should be typed.
This will cause all of the transfer  tables  to  be  cleared
forcing  all  calls  from  compiled  code  to go through the
_q_l_i_n_k_e_r function where the interrupt flag will  be  checked.
If  the  lisp  system still doesn't respond, a third ^C will
cause an  immediate  interrupt.   This  interrupt  will  not
necessarily  be in a safe place so the user should _r_e_s_e_t the
lisp system as soon as possible.








____________________
9   []Actually there are two but the lisp system does not al-
low you to catch the QUIT interrupt.



9                                     Printed: March 23, 1982