|
|
1.1 root 1:
2:
3:
4:
5:
6:
7:
8: CHAPTER 10
9:
10:
11: Exception Handling
12:
13:
14:
15:
16:
17:
18: 10.1. Errset and Error Handler Functions
19:
20: FRANZ LISP allows the user to handle in a number
21: of ways the errors which arise during computation.
22: One way is through the use of the _e_r_r_s_e_t function. If
23: an error occurs during the evaluation of the _e_r_r_s_e_t's
24: first argument, then the locus of control will return
25: to the errset which will return nil (except in special
26: cases, such as _e_r_r). The other method of error han-
27: dling is through an error handler function. When an
28: error occurs, the error handler is called and is given
29: as an argument a description of the error which just
30: occurred. The error handler may take one of the fol-
31: lowing actions:
32:
33: (1) it could take some drastic action like a _r_e_s_e_t or
34: a _t_h_r_o_w.
35:
36: (2) it could, assuming that the error is continuable,
37: return to the function which noticed the error.
38: The error handler indicates that it wants to
39: return a value from the error by returning a list
40: whose _c_a_r is the value it wants to return.
41:
42: (3) it could decide not to handle the error and
43: return a non-list to indicate this fact.
44:
45:
46:
47: 10.2. The Anatomy of an error
48:
49: Each error is described by a list of these items:
50:
51: (1) error type - This is a symbol which indicates the
52: general classification of the error. This clas-
53: sification may determine which function handles
54: this error.
55:
56: (2) unique id - This is a fixnum unique to this
57: error.
58:
59: (3) continuable - If this is non-nil then this error
60: is continuable. There are some who feel that
61:
62:
63: Exception Handling 10-1
64:
65:
66:
67:
68:
69:
70:
71: Exception Handling 10-2
72:
73:
74: every error should be continuable and the reason
75: that some (in fact most) errors in FRANZ LISP are
76: not continuable is due to the laziness of the
77: programmers.
78:
79: (4) message string - This is a symbol whose print
80: name is a message describing the error.
81:
82: (5) data - There may be from zero to three lisp
83: values which help describe this particular
84: error. For example, the unbound variable error
85: contains one datum value, the symbol whose value
86: is unbound. The list describing that error might
87: look like:
88: (ER%misc 0 t |Unbound Variable:| foobar)
89:
90:
91:
92: 10.3. Error handling algorithm
93:
94: This is the sequence of operations which is done
95: when an error occurs:
96:
97: (1) If the symbol ER%all has a non nil value then
98: this value is the name of an error handler func-
99: tion. That function is called with a description
100: of the error. If that function returns (and of
101: course it may choose not to) and the value is a
102: list and this error is continuable, then we
103: return the _c_a_r of the list to the function which
104: called the error. Presumably the function will
105: use this value to retry the operation. On the
106: other hand, if the error handler returns a non
107: list, then it has chosen not to handle this
108: error, so we go on to step (2). Something spe-
109: cial happens before we call the ER%all error
110: handler which does not happen in any of the other
111: cases we will describe below. To help insure
112: that we don't get infinitely recursive errors if
113: ER%all is set to a bad value, the value of ER%all
114: is set to nil before the handler is called. Thus
115: it is the responsibility of the ER%all handler to
116: `reenable' itself by storing its name in ER%all.
117:
118: (2) Next the specific error handler for the type of
119: error which just occurred is called (if one
120: exists) to see if it wants to handle the error.
121: The names of the handlers for the specific types
122: of errors are stored as the values of the symbols
123: whose names are the types. For example the
124: handler for miscellaneous errors is stored as the
125: value of ER%misc. Of course, if ER%misc has a
126: value of nil, then there is no error handler for
127:
128:
129: Printed: July 21, 1983
130:
131:
132:
133:
134:
135:
136:
137: Exception Handling 10-3
138:
139:
140: this type of error. Appendix B contains list of
141: all error types. The process of classifying the
142: errors is not complete and thus most errors are
143: lumped into the ER%misc category. Just as in
144: step (1), the error handler function may choose
145: not to handle the error by returning a non-list,
146: and then we go to step (3).
147:
148: (3) Next a check is made to see if there is an _e_r_r_s_e_t
149: surrounding this error. If so the second argu-
150: ment to the _e_r_r_s_e_t call is examined. If the
151: second argument was not given or is non nil then
152: the error message associated with this error is
153: printed. Finally the stack is popped to the
154: context of the _e_r_r_s_e_t and then the _e_r_r_s_e_t returns
155: nil. If there was no _e_r_r_s_e_t we go to step (4).
156:
157: (4) If the symbol ER%tpl has a value then it is the
158: name of an error handler which is called in a
159: manner similar to that discussed above. If it
160: chooses not to handle the error, we go to step
161: (5).
162:
163: (5) At this point it has been determined that the
164: user doesn't want to handle this error. Thus the
165: error message is printed out and a _r_e_s_e_t is done
166: to send the flow of control to the top-level.
167:
168: To summarize the error handling system: When an
169: error occurs, you have two chances to handle it before
170: the search for an _e_r_r_s_e_t is done. Then, if there is
171: no _e_r_r_s_e_t, you have one more chance to handle the
172: error before control jumps to the top level. Every
173: error handler works in the same way: It is given a
174: description of the error (as described in the previous
175: section). It may or may not return. If it returns,
176: then it returns either a list or a non-list. If it
177: returns a list and the error is continuable, then the
178: _c_a_r of the list is returned to the function which
179: noticed the error. Otherwise the error handler has
180: decided not to handle the error and we go on to some-
181: thing else.
182:
183:
184:
185: 10.4. Default aids
186:
187: There are two standard error handlers which will
188: probably handle the needs of most users. One of these
189: is the lisp coded function _b_r_e_a_k-_e_r_r-_h_a_n_d_l_e_r which is
190: the default value of ER%tpl. Thus when all other
191: handlers have ignored an error, _b_r_e_a_k-_e_r_r-_h_a_n_d_l_e_r will
192: take over. It will print out the error message and go
193:
194:
195: Printed: July 21, 1983
196:
197:
198:
199:
200:
201:
202:
203: Exception Handling 10-4
204:
205:
206: into a read-eval-print loop. The other standard error
207: handler is _d_e_b_u_g-_e_r_r-_h_a_n_d_l_e_r. This handler is
208: designed to be connected to ER%alland is useful if
209: your program uses _e_r_r_s_e_t and you want to look at the
210: error before it is thrown up to the _e_r_r_s_e_t.
211:
212:
213:
214: 10.5. Autoloading
215:
216: When _e_v_a_l, _a_p_p_l_y or _f_u_n_c_a_l_l are told to call an
217: undefined function, an ER%undef error is signaled.
218: The default handler for this error is _u_n_d_e_f-_f_u_n_c-
219: _h_a_n_d_l_e_r. This function checks the property list of
220: the undefined function for the indicator autoload. If
221: present, the value of that indicator should be the
222: name of the file which contains the definition of the
223: undefined function. _U_n_d_e_f-_f_u_n_c-_h_a_n_d_l_e_r will load the
224: file and check if it has defined the function which
225: caused the error. If it has, the error handler will
226: return and the computation will continue as if the
227: error did not occur. This provides a way for the user
228: to tell the lisp system about the location of commonly
229: used functions. The trace package sets up an autoload
230: property to point to /usr/lib/lisp/trace.
231:
232:
233:
234: 10.6. Interrupt processing
235:
236: The UNIX operating system provides one user
237: interrupt character which defaults to ^C.[] The user
238: may select a lisp function to run when an interrupt
239: occurs. Since this interrupt could occur at any time,
240: and in particular could occur at a time when the
241: internal stack pointers were in an inconsistent state,
242: the processing of the interrupt may be delayed until a
243: safe time. When the first ^C is typed, the lisp sys-
244: tem sets a flag that an interrupt has been requested.
245: This flag is checked at safe places within the inter-
246: preter and in the _q_l_i_n_k_e_r function. If the lisp sys-
247: tem doesn't respond to the first ^C, another ^C should
248: be typed. This will cause all of the transfer tables
249: to be cleared forcing all calls from compiled code to
250: go through the _q_l_i_n_k_e_r function where the interrupt
251: flag will be checked. If the lisp system still
252: doesn't respond, a third ^C will cause an immediate
253: interrupt. This interrupt will not necessarily be in
254: ____________________
255: 9 []Actually there are two but the lisp system does not al-
256: low you to catch the QUIT interrupt.
257:
258:
259:
260: 9 Printed: July 21, 1983
261:
262:
263:
264:
265:
266:
267:
268: Exception Handling 10-5
269:
270:
271: a safe place so the user should _r_e_s_e_t the lisp system
272: as soon as possible.
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321:
322:
323: 9
324:
325: 9 Printed: July 21, 1983
326:
327:
328:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.