|
|
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.