BSD 4_2 development
[unix-history] / usr / lisp / ch10.n
CommitLineData
2f61a98b
C
1." $Header: /na/franz/doc/RCS/ch10.n,v 1.1 83/01/31 07:08:20 jkf Exp $
2.Lc Exception\ Handling 10
3.sh 2 Errset\ and\ Error\ Handler\ Functions 10
4.pp
5.Fr
6allows the user to handle in a number of ways the errors
7which arise during computation.
8One way is through the use of the
9.i errset
10function.
11If an error occurs during the evaluation of the
12.i errset 's
13first argument, then
14the locus of control will return to the errset which will
15return nil (except in special cases, such as
16.i err ).
17The other method of error handling is through an error handler
18function.
19When an error occurs, the error handler is called and
20is given as an argument a description of the
21error which just occurred.
22The error handler may take one of the following actions:
23.nr $p 0
24.np
25it could take some drastic action like a
26.i reset
27or a
28.i throw .
29.np
30it could, assuming that the error is continuable,
31return
32to the function which noticed the error.
33The error handler indicates that it wants to return a value from
34the error by returning a list whose
35.i car
36is the value it wants to return.
37.np
38it could decide not to handle the error and return a non-list to
39indicate this fact.
40.sh 2 "The Anatomy of an error"
41.pp
42Each error is described by a list of these items:
43.nr $p 0
44.np
45error type - This is a symbol which indicates the
46general classification of the error.
47This classification may determine which function handles this
48error.
49.np
50unique id - This is a fixnum unique to this error.
51.np
52continuable - If this is non-nil then this error is continuable.
53There are some who feel that every error should be continuable
54and the reason that some (in fact most) errors in
55.Fr
56are not continuable is due to the laziness of the programmers.
57.np
58message string - This is a symbol whose print name is a
59message describing the error.
60.np
61data - There may be from zero to three lisp values which help
62describe this particular error.
63For example, the unbound variable error contains one datum value,
64the symbol whose value is unbound.
65The list describing that error might look like:
66.br
67.ce
68(ER%misc 0 t |Unbound Variable:| foobar)
69.sh 2 "Error handling algorithm"
70.pp
71This is the sequence of operations which is done when an
72error occurs:
73.nr $p 0
74.np
75If the symbol
76.b ER%all
77has a non nil value
78then this value is the name of an error handler function.
79That function is called with a description of the error.
80If that function returns (and of course it may choose not to)
81and the value is a list and this error is continuable, then
82we return the
83.i car
84of the list to the function which called the error.
85Presumably the function will use this value to retry the operation.
86On the other hand, if the error handler returns a non list, then
87it has chosen not to handle this error, so we go on to step (2).
88Something special happens before we call the
89.b ER%all
90error
91handler which does not happen in any of the
92other cases we will describe below.
93To help insure that we don't get infinitely recursive
94errors if
95.b ER%all
96is set to a bad value,
97the value of
98.b ER%all
99is set to nil before the
100handler is called.
101Thus it is the responsibility of the
102.b ER%all
103handler to `reenable'
104itself by storing its name in
105.b ER%all.
106.np
107Next the specific error handler for the type of error
108which just occurred is called (if one exists) to see if
109it wants to handle the error.
110The names of the handlers for the specific types of errors are stored
111as the values of the symbols whose names are the types.
112For example the handler for miscellaneous errors is stored as the
113value of
114.b ER%misc.
115Of course, if
116.b ER%misc
117has a value of nil, then there is no error
118handler for this type of error.
119Appendix B contains list of all error types.
120The process of classifying the errors is not complete and thus most
121errors are lumped into the \fBER%misc\fP category.
122Just as in step (1),
123the error handler function may choose not to handle the error
124by returning a non-list, and then we go to step (3).
125.np
126Next a check is made to see if there is an
127.i errset
128surrounding this error.
129If so the second argument to the
130.i errset
131call
132is examined.
133If the second argument was not given or is non nil
134then the error message associated with this error is printed.
135Finally the stack is popped
136to the context of the
137.i errset
138and then the
139.i errset
140returns nil.
141If there was no
142.i errset
143we go to step (4).
144.np
145If the symbol
146.b ER%tpl
147has a value then it is the
148name of an error handler which is called in a manner similar
149to that discussed above.
150If it chooses not to handle the error, we go to step (5).
151.np
152At this point it has been determined that the user doesn't
153want to handle this error.
154Thus the error message is printed out and
155a
156.i reset
157is done to send the flow of control to the top-level.
158.pp
159To summarize the error handling system:
160When an error occurs, you have two chances to handle it before
161the search for an
162.i errset
163is done.
164Then, if there is no
165.i errset ,
166you have one more chance to handle the error before control
167jumps to the top level.
168Every error handler works in the same way:
169It is given a description of the error (as described in the
170previous section).
171It may or may not return.
172If it returns, then it returns
173either a list or a non-list.
174If it returns a list and the error is continuable, then
175the
176.i car
177of the list is returned to the function which noticed the error.
178Otherwise the error handler has decided not to handle the error
179and we go on to something else.
180.sh 2 "Default aids"
181.pp
182There are two standard error handlers which will probably
183handle the needs of most users.
184One of these is the lisp coded function
185.i break-err-handler
186which is the default value of
187.b ER%tpl.
188Thus when all other handlers have ignored an error,
189.i break-err-handler
190will take over.
191It will print out the error message and
192go into a read-eval-print loop.
193The other standard error handler is
194.i debug-err-handler .
195This handler is designed to be connected to
196.b ER%all and
197is useful if your program uses
198.i errset
199and you want to
200look at the error before
201it is thrown up to the
202.i errset .
203.sh +0 Autoloading
204.pp
205When
206.i eval ,
207.i apply
208or
209.i funcall
210are told to call an undefined function, an \fBER%undef\fP
211error is signaled.
212The default handler for this error is
213.i undef-func-handler .
214This function checks the property list of the undefined function for
215the indicator autoload.
216If present, the value of that indicator should be the name of the file
217which contains the definition of the undefined function.
218.i Undef-func-handler
219will load the file and check if it has defined the function which caused
220the error.
221If it has, the error handler will return and the computation will continue
222as if the error did not occur.
223This provides a way for the user to tell the lisp system about the location
224of commonly used functions.
225The trace package sets up an autoload property to point to /usr/lib/lisp/trace.
226.sh +0 Interrupt\ processing
227.pp
228The UNIX operating system provides one user interrupt character which
229defaults to ^C.\*[\(dg\*]
230.(f
231\*[\(dg\*]Actually there are two but the lisp system does not allow you
232to catch the QUIT interrupt.
233.)f
234The user may select a lisp function to run when an interrupt occurs.
235Since this interrupt could occur at any time, and in particular could
236occur at a time when the internal stack pointers were in an inconsistent
237state, the processing of the interrupt may be delayed until a safe
238time.
239When the first ^C is typed, the lisp system sets a flag that an interrupt
240has been requested.
241This flag is checked at safe places within the interpreter
242and in the
243.i qlinker
244function.
245If the lisp system doesn't respond to the first ^C, another ^C should
246be typed.
247This will cause all of the transfer tables to be cleared forcing
248all calls from compiled code to go through the
249.i qlinker
250function where the interrupt flag will be checked.
251If the lisp system still doesn't respond, a third ^C will cause
252an immediate interrupt.
253This interrupt will not necessarily be in a safe place so the
254user should
255.i reset
256the lisp system as soon as possible.