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