author | Claus Gittinger <cg@exept.de> |
Thu, 09 May 1996 15:24:48 +0200 | |
changeset 1363 | 461c6d002b63 |
parent 1292 | 89497fff7f87 |
child 1376 | 6757590defbf |
permissions | -rw-r--r-- |
1 | 1 |
" |
2 |
COPYRIGHT (c) 1993 by Claus Gittinger |
|
171 | 3 |
All Rights Reserved |
1 | 4 |
|
5 |
This software is furnished under a license and may be used |
|
6 |
only in accordance with the terms of that license and with the |
|
7 |
inclusion of the above copyright notice. This software may not |
|
8 |
be provided or otherwise made available to, or used by, any |
|
9 |
other person. No title to or ownership of the software is |
|
10 |
hereby transferred. |
|
11 |
" |
|
12 |
||
13 |
Object subclass:#Exception |
|
1118
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
14 |
instanceVariableNames:'signal parameter errorString suspendedContext handlerContext |
759
908363ce8a32
interest is written with one 'r' (shame on me)
Claus Gittinger <cg@exept.de>
parents:
662
diff
changeset
|
15 |
rejected originator resumeBlock rejectBlock' |
1118
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
16 |
classVariableNames:'EmergencyHandler RecursiveExceptionSignal' |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
17 |
poolDictionaries:'' |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
18 |
category:'Kernel-Exceptions' |
1 | 19 |
! |
20 |
||
12 | 21 |
!Exception class methodsFor:'documentation'! |
22 |
||
88 | 23 |
copyright |
24 |
" |
|
25 |
COPYRIGHT (c) 1993 by Claus Gittinger |
|
171 | 26 |
All Rights Reserved |
88 | 27 |
|
28 |
This software is furnished under a license and may be used |
|
29 |
only in accordance with the terms of that license and with the |
|
30 |
inclusion of the above copyright notice. This software may not |
|
31 |
be provided or otherwise made available to, or used by, any |
|
32 |
other person. No title to or ownership of the software is |
|
33 |
hereby transferred. |
|
34 |
" |
|
35 |
! |
|
36 |
||
12 | 37 |
documentation |
38 |
" |
|
68 | 39 |
Instances of Exception are passed to a Signal handling block as argument. |
40 |
The handler block may perform various actions by sending corresponding messages |
|
142 | 41 |
to the exception object. The following actions are possible: |
1 | 42 |
|
1274 | 43 |
reject - dont handle this signal; |
44 |
another handler will be searched for, |
|
45 |
upper in the calling hierarchy |
|
1 | 46 |
|
1274 | 47 |
proceed - return from the Signal>>raise, with nil as value |
142 | 48 |
|
1274 | 49 |
proceedWith:val - same, but return val from Signal>>raise |
1 | 50 |
|
1274 | 51 |
return - return from the Signal>>handle:do:, with nil as value |
142 | 52 |
|
1274 | 53 |
returnWith:val - same, but return val from Signal>>handle:do: |
54 |
(this is also the handlers default, |
|
55 |
if it falls through; taking the handlerBlocks value |
|
56 |
as return value) |
|
1 | 57 |
|
1274 | 58 |
restart - restart the Signal>>handle:do:, after repairing |
1 | 59 |
|
142 | 60 |
Via the Exception object, the handler can also query the state of execution: |
68 | 61 |
where the Signal was raised, where the handler is, the signal which caused |
142 | 62 |
the error and the errorString passed when the signal was raised. Also, an optional |
63 |
parameter can be passed - the use is signal specific.: |
|
44 | 64 |
|
1274 | 65 |
[instance variables:] |
66 |
signal <Signal> the signal which caused the exception |
|
142 | 67 |
|
1274 | 68 |
parameter <Object> a parameter (if any) which was passed when raising |
69 |
the signal (only if raised with #raiseWith:aParameter) |
|
142 | 70 |
|
1274 | 71 |
errorString <String> an errorString |
72 |
(usually the signals own errorString, but sometimes |
|
73 |
changed explicitely in #raiseWith:errorString:) |
|
44 | 74 |
|
1274 | 75 |
suspendedContext <Context> the context in which the raise occured |
142 | 76 |
|
1274 | 77 |
handlerContext <Context> the context of the handler (if any) |
142 | 78 |
|
1274 | 79 |
resumeBlock <Block> private to the exception; needed to perform resume action |
44 | 80 |
|
1274 | 81 |
rejectBlock <Block> private to the exception; needed to perform reject action |
44 | 82 |
|
142 | 83 |
In case of an unhandled signal raise, Exceptions EmergenyHandler will be evaluated. |
68 | 84 |
The default emergeny handler will enter the debugger. |
142 | 85 |
|
68 | 86 |
For applications, which do not want Debuggers to come up, other handlers are |
87 |
possible. |
|
362 | 88 |
For example, to get the typical C++ behavior, use: |
1274 | 89 |
Exception emergencyHandler:[:ex | Smalltalk exitWithCoreDump] |
68 | 90 |
|
1274 | 91 |
|
92 |
[Class variables:] |
|
93 |
EmergencyHandler <Block> this block is evaluated, if no handler was defined |
|
94 |
for a signal (i.e. this one is responsible for the |
|
95 |
unhandled exception debugger). |
|
96 |
Having this being a block allows to globally catch |
|
97 |
these errors - even when no enclosing handler-scope |
|
98 |
around the erronous code exists. |
|
99 |
(as the catch/through does). |
|
171 | 100 |
|
1274 | 101 |
RecursiveExceptionSignal |
102 |
<Signal> raised when within a handler for some signal, |
|
103 |
the same signal is raised again. |
|
104 |
||
105 |
||
106 |
[see also:] |
|
1363 | 107 |
Signal SignalSet QuerySignal |
1274 | 108 |
Context Block |
109 |
Object DebugView |
|
1363 | 110 |
(``Exception handling and signals'': programming/exceptions.html) |
1292 | 111 |
|
112 |
[author:] |
|
113 |
Claus Gittinger |
|
12 | 114 |
" |
115 |
! ! |
|
3 | 116 |
|
171 | 117 |
!Exception class methodsFor:'initialization'! |
118 |
||
119 |
initialize |
|
120 |
"setup the signal used to handle unhandled signals" |
|
121 |
||
122 |
RecursiveExceptionSignal isNil ifTrue:[ |
|
302 | 123 |
RecursiveExceptionSignal := ErrorSignal newSignalMayProceed:false. |
171 | 124 |
RecursiveExceptionSignal nameClass:self message:#recursiveExceptionSignal. |
125 |
RecursiveExceptionSignal notifierString:'recursive signal raise in handler' |
|
126 |
] |
|
127 |
! ! |
|
128 |
||
621 | 129 |
!Exception class methodsFor:'instance creation'! |
130 |
||
131 |
signal:aSignal parameter:aParameter errorString:aString suspendedContext:sContext |
|
132 |
"create a new instance and set the fields in preparation for a raise. |
|
133 |
- only to be sent from the signal when raising" |
|
134 |
||
135 |
^ (self new) |
|
136 |
signal:aSignal |
|
137 |
parameter:aParameter |
|
138 |
errorString:aString |
|
139 |
suspendedContext:sContext |
|
140 |
originator:(sContext receiver). |
|
141 |
! |
|
142 |
||
143 |
signal:aSignal parameter:aParameter errorString:aString suspendedContext:sContext originator:origin |
|
144 |
"create a new instance and set the fields in preparation for a raise. |
|
145 |
- only to be sent from the signal when raising" |
|
146 |
||
147 |
^ (self new) |
|
148 |
signal:aSignal |
|
149 |
parameter:aParameter |
|
150 |
errorString:aString |
|
151 |
suspendedContext:sContext |
|
152 |
originator:origin. |
|
153 |
! ! |
|
154 |
||
345 | 155 |
!Exception class methodsFor:'Signal constants'! |
171 | 156 |
|
157 |
recursiveExceptionSignal |
|
158 |
"return the signal used to handle recursive signals in the handlers" |
|
159 |
||
160 |
^ RecursiveExceptionSignal |
|
161 |
! ! |
|
162 |
||
12 | 163 |
!Exception class methodsFor:'defaults'! |
164 |
||
165 |
emergencyHandler |
|
166 |
"return the handler used for unhandled exceptions" |
|
167 |
||
77 | 168 |
" |
169 |
set it up, when called the first time |
|
170 |
" |
|
171 |
EmergencyHandler isNil ifTrue:[ |
|
171 | 172 |
EmergencyHandler := [:ex | |
173 |
" |
|
174 |
sending it to the signal allows per-signal specific |
|
175 |
debuggers to be implemented in the future |
|
176 |
(for example, segv in primitive code could show things |
|
177 |
on the C-level ..) |
|
178 |
" |
|
179 |
(ex signal) enterDebuggerWith:ex message:(ex errorString). |
|
180 |
] |
|
77 | 181 |
]. |
182 |
||
12 | 183 |
^ EmergencyHandler |
184 |
! |
|
185 |
||
130 | 186 |
emergencyHandler:aOneArgBlock |
12 | 187 |
"set the handler used for unhandled exceptions" |
188 |
||
130 | 189 |
EmergencyHandler := aOneArgBlock |
362 | 190 |
|
191 |
"ST-80 behavior of first showing a notifier: |
|
192 |
(I prefer to get right into the debugger, though) |
|
193 |
||
194 |
Exception |
|
195 |
emergencyHandler: |
|
547 | 196 |
[:ex | self errorNotify:ex errorString ] |
362 | 197 |
" |
198 |
||
199 |
"automatically aborting current operation, on error: |
|
200 |
(may be useful for end-user apps; make certain, |
|
201 |
you have abortSignal handlers at appropriate places) |
|
202 |
||
203 |
Exception |
|
204 |
emergencyHandler: |
|
205 |
[:ex | Object abortSignal raise. ex return. ] |
|
206 |
" |
|
207 |
||
208 |
"finally, traditional language system behavior; dump core ;-) |
|
209 |
||
210 |
Exception |
|
211 |
emergencyHandler: |
|
212 |
[:ex | Smalltalk exitWithCoreDump. ] |
|
213 |
" |
|
214 |
! ! |
|
215 |
||
1 | 216 |
!Exception methodsFor:'accessing'! |
217 |
||
44 | 218 |
errorString |
219 |
"return the errorString passsed with the signal raise |
|
220 |
(or nil, if there was none)" |
|
221 |
||
222 |
^ errorString |
|
223 |
! |
|
224 |
||
621 | 225 |
handlerContext |
226 |
"return the context of the handler" |
|
227 |
||
228 |
^ handlerContext |
|
229 |
! |
|
230 |
||
362 | 231 |
originator |
232 |
"return the originator passsed with the signal raise |
|
233 |
(or nil, if there was none)" |
|
234 |
||
235 |
^ originator |
|
236 |
! |
|
237 |
||
621 | 238 |
parameter |
239 |
"return the parameter passsed with the signal raise |
|
240 |
(or nil, if there was none)" |
|
44 | 241 |
|
621 | 242 |
^ parameter |
68 | 243 |
! |
244 |
||
245 |
rejected |
|
362 | 246 |
"return true, if any other of the exceptions handlers has rejected |
759
908363ce8a32
interest is written with one 'r' (shame on me)
Claus Gittinger <cg@exept.de>
parents:
662
diff
changeset
|
247 |
Uncertain, if this is really interesting to anybody. |
362 | 248 |
This is only valid during handler execution. |
249 |
(i.e. an outer handler can find out, if any other handler has already |
|
250 |
rejected). |
|
251 |
" |
|
68 | 252 |
|
253 |
^ rejected |
|
362 | 254 |
! |
255 |
||
621 | 256 |
signal |
257 |
"return the signal, that caused the exception" |
|
258 |
||
259 |
^ signal |
|
260 |
! |
|
261 |
||
262 |
suspendedContext |
|
263 |
"return the context in which the raise occured" |
|
264 |
||
265 |
^ suspendedContext |
|
266 |
! |
|
267 |
||
362 | 268 |
willProceed |
269 |
"return true, if the exception is proceedable" |
|
270 |
||
271 |
^ resumeBlock notNil |
|
1 | 272 |
! ! |
273 |
||
621 | 274 |
!Exception methodsFor:'handler actions'! |
275 |
||
276 |
proceed |
|
277 |
"Continue after the raise - the raise returns nil" |
|
278 |
||
279 |
resumeBlock notNil ifTrue:[resumeBlock value:nil] |
|
280 |
! |
|
281 |
||
282 |
proceedWith:value |
|
283 |
"Continue after the raise - the raise returns value" |
|
284 |
||
285 |
resumeBlock notNil ifTrue:[resumeBlock value:value] |
|
286 |
! |
|
1 | 287 |
|
621 | 288 |
reject |
289 |
"handler decided not to handle this signal - |
|
290 |
system will look for another handler" |
|
291 |
||
292 |
rejected := true. |
|
293 |
rejectBlock value |
|
294 |
! |
|
295 |
||
296 |
restart |
|
297 |
"restart the handle:do: - usually after some repair work is done |
|
298 |
in handler" |
|
299 |
||
300 |
handlerContext unwindAndRestart |
|
301 |
! |
|
1 | 302 |
|
621 | 303 |
resume |
304 |
"Continue after the raise - the raise returns nil" |
|
305 |
||
306 |
resumeBlock notNil ifTrue:[resumeBlock value:nil] |
|
307 |
! |
|
308 |
||
309 |
resumeWith:value |
|
310 |
"Continue after the raise - the raise returns value" |
|
311 |
||
312 |
resumeBlock notNil ifTrue:[resumeBlock value:value] |
|
313 |
! |
|
314 |
||
315 |
return |
|
316 |
"Continue after the handle:do: - the handle:do: returns nil" |
|
317 |
||
318 |
handlerContext unwind |
|
319 |
! |
|
320 |
||
321 |
returnDoing:aBlock |
|
322 |
"Continue after the handle:do: - the handle:do: returns aBlock value" |
|
323 |
||
324 |
handlerContext unwindThenDo:aBlock |
|
325 |
! |
|
326 |
||
327 |
returnWith:value |
|
328 |
"Continue after the handle:do: - the handle:do: returns value" |
|
329 |
||
330 |
handlerContext unwind:value |
|
171 | 331 |
! ! |
332 |
||
217 | 333 |
!Exception methodsFor:'raising'! |
1 | 334 |
|
621 | 335 |
doCallHandler:aHandler |
336 |
"call the handler proper - needed an extra method |
|
337 |
to have a separate returnContext for the rejectBlock. |
|
338 |
(which is historical, and actually no longer needed)" |
|
339 |
||
340 |
|val| |
|
362 | 341 |
|
621 | 342 |
rejectBlock := [^ self]. "this will return on reject" |
343 |
val := aHandler value:self. |
|
344 |
" |
|
345 |
handler fall through - is just like a returnWith:blocks-value |
|
346 |
" |
|
347 |
self returnWith:val |
|
1 | 348 |
! |
349 |
||
171 | 350 |
evaluateHandler |
351 |
"search through the context-calling chain for a 'handle:do:'-context |
|
352 |
to the raising signal a parent of it or a SignalSet which includes |
|
353 |
the raising signal. |
|
354 |
If found, take the contexts 2nd argument (the handler) and evaluate |
|
355 |
it with the receiver exception as argument. |
|
217 | 356 |
If no handler is found, try per signal handler, or |
357 |
per process handler (if its the noHandlerSignal). |
|
358 |
Finally fall back to Exceptions emergencyHandler, which is always |
|
359 |
available and enters the debugger." |
|
171 | 360 |
|
950
1ead6817a6c8
dont use con args (use con argAt) - this avoids creating an array copy
Claus Gittinger <cg@exept.de>
parents:
759
diff
changeset
|
361 |
|con block noHandlerSignal any msg sel activeHandler conArg1| |
171 | 362 |
|
363 |
con := thisContext sender. "the raise-context" |
|
364 |
con := con sender. "the signal raise context" |
|
365 |
con isRecursive ifTrue:[ |
|
1363 | 366 |
con := nil. |
1118
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
367 |
" |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
368 |
mhmh - an error while in a handler |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
369 |
" |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
370 |
((signal == RecursiveExceptionSignal) |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
371 |
or:[RecursiveExceptionSignal isNil]) ifTrue:[ |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
372 |
" |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
373 |
... either while handling RecursiveExceptionSignal |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
374 |
or at startup when RecursiveExceptionSignal is not yet |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
375 |
created - |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
376 |
- go immediately into the debugger. |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
377 |
" |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
378 |
^ self enterDebuggerWith:self |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
379 |
message:'recursive signal raise' |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
380 |
]. |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
381 |
^ RecursiveExceptionSignal |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
382 |
raiseRequestWith:self |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
383 |
errorString:('recursive signal raise: ' , errorString) |
171 | 384 |
]. |
385 |
||
362 | 386 |
any := false. |
171 | 387 |
[con notNil] whileTrue:[ |
1118
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
388 |
con isBlockContext ifFalse:[ |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
389 |
sel := con selector. |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
390 |
sel == #doCallHandler: ifTrue:[ |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
391 |
activeHandler := con argAt:1 |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
392 |
]. |
367 | 393 |
|
1118
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
394 |
((sel == #'handle:do:') |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
395 |
or:[((sel == #'handle:from:do:') |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
396 |
and:[(con argAt:2) == originator])]) ifTrue:[ |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
397 |
" |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
398 |
if this is the Signal>>handle:do: context |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
399 |
or a SignalSet>>handle:do: context with self in it, |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
400 |
call the handler |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
401 |
" |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
402 |
(con receiver accepts:signal) ifTrue:[ |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
403 |
"call the handler" |
171 | 404 |
|
1118
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
405 |
conArg1 := con argAt:1. |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
406 |
activeHandler == conArg1 ifTrue:[ |
367 | 407 |
"/ 'skip active handler:' print. |
408 |
"/ con print. ' ' print. con receiver print. |
|
409 |
"/ ' for ' print. signal printNL |
|
1118
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
410 |
] ifFalse:[ |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
411 |
handlerContext := con. |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
412 |
any := true. |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
413 |
self doCallHandler:conArg1. |
1 | 414 |
|
1118
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
415 |
"if the handler rejects, we arrive here" |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
416 |
"continue search for another handler" |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
417 |
] |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
418 |
]. |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
419 |
] |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
420 |
]. |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
421 |
con := con sender |
171 | 422 |
]. |
423 |
||
424 |
" |
|
425 |
we arrive here, if either no handler was found, or none of the |
|
426 |
handlers did a return (i.e. every handler rejected or fell through). |
|
427 |
" |
|
428 |
" |
|
429 |
try per signal handler |
|
430 |
" |
|
1038 | 431 |
(block := signal handlerBlock) isNil ifTrue:[ |
1118
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
432 |
"/ |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
433 |
"/ if its a querySIgnal, ignore it |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
434 |
"/ |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
435 |
signal isQuerySignal ifTrue:[^ self]. |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
436 |
|
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
437 |
"/ |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
438 |
"/ if it is not the NoHandlerSignal, raise it ... |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
439 |
"/ passing the receiver as parameter. |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
440 |
"/ |
1038 | 441 |
signal ~~ (noHandlerSignal := Signal noHandlerSignal) ifTrue:[ |
1118
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
442 |
noHandlerSignal notNil ifTrue:[ |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
443 |
any ifTrue:[ |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
444 |
msg := 'unhandled (rejected)' |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
445 |
] ifFalse:[ |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
446 |
msg := 'unhandled' |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
447 |
]. |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
448 |
^ noHandlerSignal |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
449 |
raiseRequestWith:self |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
450 |
errorString:(msg , ' exception: ' , errorString) |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
451 |
in:self suspendedContext |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
452 |
]. |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
453 |
"/ |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
454 |
"/ mhmh - an error during early startup; noHandlerSignal is |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
455 |
"/ not yet defined. |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
456 |
"/ |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
457 |
^ MiniDebugger enterWithMessage:errorString |
1038 | 458 |
]. |
171 | 459 |
|
1038 | 460 |
" |
461 |
mhmh - smells like trouble - there is no handler and |
|
462 |
no per-signal handler block. |
|
463 |
Look for either a per-process emergencyHandlerBlock |
|
464 |
or the global emergencyHandler (from Exception) ... |
|
465 |
" |
|
466 |
Processor notNil ifTrue:[ |
|
1118
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
467 |
"care for signal during startup (Processor not yet created)" |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
468 |
block := Processor activeProcess emergencySignalHandler. |
1038 | 469 |
]. |
470 |
block isNil ifTrue:[ |
|
1118
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
471 |
block := Exception emergencyHandler. |
1038 | 472 |
block isNil ifTrue:[ |
1118
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
473 |
"care for error during startup (Exception not yet initialized)" |
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
474 |
^ MiniDebugger enterWithMessage:errorString |
1038 | 475 |
]. |
476 |
]. |
|
171 | 477 |
]. |
478 |
"... and call it" |
|
479 |
^ block value:self. |
|
1118
1037616d9add
ignore unhandled querySignals
Claus Gittinger <cg@exept.de>
parents:
1038
diff
changeset
|
480 |
|
1363 | 481 |
"Modified: 9.5.1996 / 15:04:30 / cg" |
1 | 482 |
! |
483 |
||
621 | 484 |
raise |
485 |
"actually raise a nonproceedable exception. |
|
486 |
For now, same as #raiseRequest (always proceedable)." |
|
1 | 487 |
|
621 | 488 |
resumeBlock := [:value | ^ value]. |
489 |
^ self evaluateHandler |
|
1 | 490 |
! |
491 |
||
621 | 492 |
raiseRequest |
493 |
"actually raise a proceedable exception." |
|
1 | 494 |
|
621 | 495 |
resumeBlock := [:value | ^ value]. |
496 |
^ self evaluateHandler |
|
497 |
! ! |
|
1 | 498 |
|
621 | 499 |
!Exception methodsFor:'setup'! |
1 | 500 |
|
621 | 501 |
signal:aSignal parameter:aParameter errorString:aString suspendedContext:sContext originator:origin |
502 |
"set the fields usable for inspection by the handler |
|
503 |
- only to be sent from the signal when raising" |
|
328 | 504 |
|
621 | 505 |
signal := aSignal. |
506 |
parameter := aParameter. |
|
507 |
errorString := aString. |
|
508 |
suspendedContext := sContext. |
|
509 |
originator := origin. |
|
510 |
! ! |
|
328 | 511 |
|
662 | 512 |
!Exception class methodsFor:'documentation'! |
513 |
||
514 |
version |
|
1363 | 515 |
^ '$Header: /cvs/stx/stx/libbasic/Exception.st,v 1.36 1996-05-09 13:24:48 cg Exp $' |
662 | 516 |
! ! |
621 | 517 |
Exception initialize! |