38 " |
38 " |
39 Instances of Exception are passed to a Signal handling block as argument. |
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 |
40 The handler block may perform various actions by sending corresponding messages |
41 to the exception object. The following actions are possible: |
41 to the exception object. The following actions are possible: |
42 |
42 |
43 reject - dont handle this signal; |
43 reject - dont handle this signal; |
44 another handler will be searched for, |
44 another handler will be searched for, |
45 upper in the calling hierarchy |
45 upper in the calling hierarchy |
46 |
46 |
47 proceed - return from the Signal>>raise, with nil as value |
47 proceed - return from the Signal>>raise, with nil as value |
48 |
48 |
49 proceedWith:val - same, but return val from Signal>>raise |
49 proceedWith:val - same, but return val from Signal>>raise |
50 |
50 |
51 return - return from the Signal>>handle:do:, with nil as value |
51 return - return from the Signal>>handle:do:, with nil as value |
52 |
52 |
53 returnWith:val - same, but return val from Signal>>handle:do: |
53 returnWith:val - same, but return val from Signal>>handle:do: |
54 (this is also the handlers default, |
54 (this is also the handlers default, |
55 if it falls through; taking the handlerBlocks value |
55 if it falls through; taking the handlerBlocks value |
56 as return value) |
56 as return value) |
57 |
57 |
58 restart - restart the Signal>>handle:do:, after repairing |
58 restart - restart the Signal>>handle:do:, after repairing |
59 |
59 |
60 Via the Exception object, the handler can also query the state of execution: |
60 Via the Exception object, the handler can also query the state of execution: |
61 where the Signal was raised, where the handler is, the signal which caused |
61 where the Signal was raised, where the handler is, the signal which caused |
62 the error and the errorString passed when the signal was raised. Also, an optional |
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.: |
63 parameter can be passed - the use is signal specific.: |
64 |
64 |
65 [instance variables:] |
65 [instance variables:] |
66 signal <Signal> the signal which caused the exception |
66 signal <Signal> the signal which caused the exception |
67 |
67 |
68 parameter <Object> a parameter (if any) which was passed when raising |
68 parameter <Object> a parameter (if any) which was passed when raising |
69 the signal (only if raised with #raiseWith:aParameter) |
69 the signal (only if raised with #raiseWith:aParameter) |
70 |
70 |
71 errorString <String> an errorString |
71 errorString <String> an errorString |
72 (usually the signals own errorString, but sometimes |
72 (usually the signals own errorString, but sometimes |
73 changed explicitely in #raiseWith:errorString:) |
73 changed explicitely in #raiseWith:errorString:) |
74 |
74 |
75 suspendedContext <Context> the context in which the raise occured |
75 suspendedContext <Context> the context in which the raise occured |
76 |
76 |
77 handlerContext <Context> the context of the handler (if any) |
77 handlerContext <Context> the context of the handler (if any) |
78 |
78 |
79 resumeBlock <Block> private to the exception; needed to perform resume action |
79 resumeBlock <Block> private to the exception; needed to perform resume action |
80 |
80 |
81 rejectBlock <Block> private to the exception; needed to perform reject action |
81 rejectBlock <Block> private to the exception; needed to perform reject action |
82 |
82 |
83 In case of an unhandled signal raise, Exceptions EmergenyHandler will be evaluated. |
83 In case of an unhandled signal raise, Exceptions EmergenyHandler will be evaluated. |
84 The default emergeny handler will enter the debugger. |
84 The default emergeny handler will enter the debugger. |
85 |
85 |
86 For applications, which do not want Debuggers to come up, other handlers are |
86 For applications, which do not want Debuggers to come up, other handlers are |
87 possible. |
87 possible. |
88 For example, to get the typical C++ behavior, use: |
88 For example, to get the typical C++ behavior, use: |
89 Exception emergencyHandler:[:ex | Smalltalk exitWithCoreDump] |
89 Exception emergencyHandler:[:ex | Smalltalk exitWithCoreDump] |
90 |
90 |
91 |
91 |
92 [Class variables:] |
92 [Class variables:] |
93 EmergencyHandler <Block> this block is evaluated, if no handler was defined |
93 EmergencyHandler <Block> this block is evaluated, if no handler was defined |
94 for a signal (i.e. this one is responsible for the |
94 for a signal (i.e. this one is responsible for the |
95 unhandled exception debugger). |
95 unhandled exception debugger). |
96 Having this being a block allows to globally catch |
96 Having this being a block allows to globally catch |
97 these errors - even when no enclosing handler-scope |
97 these errors - even when no enclosing handler-scope |
98 around the erronous code exists. |
98 around the erronous code exists. |
99 (as the catch/through does). |
99 (as the catch/through does). |
100 |
100 |
101 RecursiveExceptionSignal |
101 RecursiveExceptionSignal |
102 <Signal> raised when within a handler for some signal, |
102 <Signal> raised when within a handler for some signal, |
103 the same signal is raised again. |
103 the same signal is raised again. |
104 |
104 |
105 |
105 |
106 [see also:] |
106 [see also:] |
107 Signal SignalSet QuerySignal |
107 Signal SignalSet QuerySignal |
108 Context Block |
108 Context Block |
109 Object DebugView |
109 Object DebugView |
110 (``Exception handling and signals'': programming/exceptions.html) |
110 (``Exception handling and signals'': programming/exceptions.html) |
111 |
111 |
112 [author:] |
112 [author:] |
113 Claus Gittinger |
113 Claus Gittinger |
114 " |
114 " |
115 ! |
115 ! |
116 |
116 |
117 examples |
117 examples |
118 " |
118 " |
303 This is useful, for endUser application, which are still being |
303 This is useful, for endUser application, which are still being |
304 debugged (i.e. the programmers may have a look at the traceFile |
304 debugged (i.e. the programmers may have a look at the traceFile |
305 from time to time). |
305 from time to time). |
306 |
306 |
307 Notice: |
307 Notice: |
308 The code below is just an example; you may want to change the |
308 The code below is just an example; you may want to change the |
309 name of the error-file in your application |
309 name of the error-file in your application |
310 (but please: copy the code; do not modify here)" |
310 (but please: copy the code; do not modify here)" |
311 |
311 |
312 ^ [:ex | |
312 ^ [:ex | |
313 |str printedException| |
313 |str printedException| |
314 |
314 |
315 ex signal == Signal noHandlerSignal ifTrue:[ |
315 ex signal == Signal noHandlerSignal ifTrue:[ |
316 printedException := ex parameter. |
316 printedException := ex parameter. |
317 ] ifFalse:[ |
317 ] ifFalse:[ |
318 printedException := ex |
318 printedException := ex |
319 ]. |
319 ]. |
320 |
320 |
321 "/ user interruption is handled specially: |
321 "/ user interruption is handled specially: |
322 "/ allow user to choose between proceeding or aborting |
322 "/ allow user to choose between proceeding or aborting |
323 "/ but never dump that information to the file. |
323 "/ but never dump that information to the file. |
324 |
324 |
325 printedException signal == Object userInterruptSignal ifTrue:[ |
325 printedException signal == Object userInterruptSignal ifTrue:[ |
326 (self confirm:'abort current action ?') ifTrue:[ |
326 (self confirm:'abort current action ?') ifTrue:[ |
327 AbortSignal raise |
327 AbortSignal raise |
328 ]. |
328 ]. |
329 ex proceed |
329 ex proceed |
330 ]. |
330 ]. |
331 |
331 |
332 "/ |
332 "/ |
333 "/ dump it to 'errorTrace.stx' |
333 "/ dump it to 'errorTrace.stx' |
334 "/ |
334 "/ |
335 str := 'errorTrace.stx' asFilename appendingWriteStream. |
335 str := 'errorTrace.stx' asFilename appendingWriteStream. |
336 |
336 |
337 str nextPutLine:('******************************* ' |
337 str nextPutLine:('******************************* ' |
338 , AbsoluteTime now printString |
338 , AbsoluteTime now printString |
339 , ' *******************************'). |
339 , ' *******************************'). |
340 str cr. |
340 str cr. |
341 |
341 |
342 str nextPutLine:('** Error: ' , printedException errorString). |
342 str nextPutLine:('** Error: ' , printedException errorString). |
343 str nextPutLine:('** Signal: ' , printedException signal printString). |
343 str nextPutLine:('** Signal: ' , printedException signal printString). |
344 str nextPutLine:('** Parameter: ' , printedException parameter printString). |
344 str nextPutLine:('** Parameter: ' , printedException parameter printString). |
345 str nextPutLine:('** Process: ' , Processor activeProcess printString). |
345 str nextPutLine:('** Process: ' , Processor activeProcess printString). |
346 str nextPutLine:('** Backtrace:'). |
346 str nextPutLine:('** Backtrace:'). |
347 str cr. |
347 str cr. |
348 |
348 |
349 printedException suspendedContext fullPrintAllOn:str. |
349 printedException suspendedContext fullPrintAllOn:str. |
350 str cr. |
350 str cr. |
351 str cr. |
351 str cr. |
352 str close. |
352 str close. |
353 |
353 |
354 self warn:printedException errorString. |
354 self warn:printedException errorString. |
355 AbortSignal raise |
355 AbortSignal raise |
356 ] |
356 ] |
357 |
357 |
358 "test with (try a few halts or CTRL-C's): |
358 "test with (try a few halts or CTRL-C's): |
359 Exception emergencyHandler:(Exception dumpingEmergencyHandler) |
359 Exception emergencyHandler:(Exception dumpingEmergencyHandler) |
360 " |
360 " |
373 which shows a warnBox and optionally mails a stackBacktrace to a maintainer. |
373 which shows a warnBox and optionally mails a stackBacktrace to a maintainer. |
374 This is useful, for endUser application, which are still being |
374 This is useful, for endUser application, which are still being |
375 debugged (i.e. the programmers may have a look at the errors). |
375 debugged (i.e. the programmers may have a look at the errors). |
376 |
376 |
377 Notice: the stuff here is a demonstration only; it should be modified |
377 Notice: the stuff here is a demonstration only; it should be modified |
378 for your particular environment ... |
378 for your particular environment ... |
379 ... but please: copy the code and modify there; |
379 ... but please: copy the code and modify there; |
380 leave the stuff below as it is." |
380 leave the stuff below as it is." |
381 |
381 |
382 ^ [:ex | |
382 ^ [:ex | |
383 |str printedException doMail emergencyMailReceiver pipe| |
383 |str printedException doMail emergencyMailReceiver pipe| |
384 |
384 |
385 ex signal == Signal noHandlerSignal ifTrue:[ |
385 ex signal == Signal noHandlerSignal ifTrue:[ |
386 printedException := ex parameter. |
386 printedException := ex parameter. |
387 ] ifFalse:[ |
387 ] ifFalse:[ |
388 printedException := ex |
388 printedException := ex |
389 ]. |
389 ]. |
390 |
390 |
391 "/ user interruption is handled specially: |
391 "/ user interruption is handled specially: |
392 "/ allow user to choose between proceeding or aborting |
392 "/ allow user to choose between proceeding or aborting |
393 "/ but never dump that information to the file. |
393 "/ but never dump that information to the file. |
394 |
394 |
395 printedException signal == Object userInterruptSignal ifTrue:[ |
395 printedException signal == Object userInterruptSignal ifTrue:[ |
396 (self confirm:'abort current action ?') ifTrue:[ |
396 (self confirm:'abort current action ?') ifTrue:[ |
397 AbortSignal raise |
397 AbortSignal raise |
398 ]. |
398 ]. |
399 ex proceed |
399 ex proceed |
400 ]. |
400 ]. |
401 |
401 |
402 "/ somehow get the name of the guy to receive the mail |
402 "/ somehow get the name of the guy to receive the mail |
403 "/ you have to implement that yourself. |
403 "/ you have to implement that yourself. |
404 |
404 |
405 "/ emergencyMailReceiver := OneOfYourClass getEmergencyMailReceiver. |
405 "/ emergencyMailReceiver := OneOfYourClass getEmergencyMailReceiver. |
406 emergencyMailReceiver := OperatingSystem getLoginName. |
406 emergencyMailReceiver := OperatingSystem getLoginName. |
407 |
407 |
408 emergencyMailReceiver isNil ifTrue:[ |
408 emergencyMailReceiver isNil ifTrue:[ |
409 self warn:(printedException errorString |
409 self warn:(printedException errorString |
410 , '\\No mailing to service people possible.') withCRs. |
410 , '\\No mailing to service people possible.') withCRs. |
411 doMail := false. |
411 doMail := false. |
412 ] ifFalse:[ |
412 ] ifFalse:[ |
413 doMail := self confirm:(printedException errorString |
413 doMail := self confirm:(printedException errorString |
414 , '\\Mail error information to the service people (' |
414 , '\\Mail error information to the service people (' |
415 , emergencyMailReceiver , ') ?') withCRs |
415 , emergencyMailReceiver , ') ?') withCRs |
416 ]. |
416 ]. |
417 doMail ifTrue:[ |
417 doMail ifTrue:[ |
418 str := '' writeStream. |
418 str := '' writeStream. |
419 |
419 |
420 str nextPutLine:('Error notification from ' |
420 str nextPutLine:('Error notification from ' |
421 , OperatingSystem getLoginName |
421 , OperatingSystem getLoginName |
422 , '@' |
422 , '@' |
423 , OperatingSystem getHostName). |
423 , OperatingSystem getHostName). |
424 str cr. |
424 str cr. |
425 |
425 |
426 str nextPutLine:('Time: ' , AbsoluteTime now printString). |
426 str nextPutLine:('Time: ' , AbsoluteTime now printString). |
427 str nextPutLine:('Error: ', printedException errorString). |
427 str nextPutLine:('Error: ', printedException errorString). |
428 str nextPutLine:('Signal: ', printedException signal printString). |
428 str nextPutLine:('Signal: ', printedException signal printString). |
429 str nextPutLine:('Parameter: ', printedException parameter printString). |
429 str nextPutLine:('Parameter: ', printedException parameter printString). |
430 str nextPutLine:('Process: ', Processor activeProcess printString). |
430 str nextPutLine:('Process: ', Processor activeProcess printString). |
431 str nextPutLine:'Backtrace:'. |
431 str nextPutLine:'Backtrace:'. |
432 str cr. |
432 str cr. |
433 |
433 |
434 printedException suspendedContext fullPrintAllOn:str. |
434 printedException suspendedContext fullPrintAllOn:str. |
435 str cr;cr. |
435 str cr;cr. |
436 |
436 |
437 str close. |
437 str close. |
438 |
438 |
439 pipe := PipeStream |
439 pipe := PipeStream |
440 writingTo:'mail ', emergencyMailReceiver. |
440 writingTo:'mail ', emergencyMailReceiver. |
441 pipe notNil ifTrue:[ |
441 pipe notNil ifTrue:[ |
442 pipe nextPutLine:'Subject: automatic error report'. |
442 pipe nextPutLine:'Subject: automatic error report'. |
443 pipe nextPutAll:str contents. |
443 pipe nextPutAll:str contents. |
444 pipe cr. |
444 pipe cr. |
445 pipe close. |
445 pipe close. |
446 ] |
446 ] |
447 ]. |
447 ]. |
448 |
448 |
449 AbortSignal raise |
449 AbortSignal raise |
450 ] |
450 ] |
451 |
451 |
452 "test with (try a few halts or CTRL-C's): |
452 "test with (try a few halts or CTRL-C's): |
453 Exception emergencyHandler:(Exception mailingEmergencyHandler) |
453 Exception emergencyHandler:(Exception mailingEmergencyHandler) |
454 " |
454 " |
649 "/ from within a handler (which would lead to re-executing the |
649 "/ from within a handler (which would lead to re-executing the |
650 "/ same handler) |
650 "/ same handler) |
651 "/ the code below collects active handlers ... |
651 "/ the code below collects active handlers ... |
652 |
652 |
653 [c notNil] whileTrue:[ |
653 [c notNil] whileTrue:[ |
654 sel := c selector. |
654 c := c findContextWithSelector:#doRaise or:nil. |
655 sel == #doRaise ifTrue:[ |
655 c notNil ifTrue:[ |
656 ex1 := c receiver. |
656 |
657 ex1 species == self species ifTrue:[ |
657 ex1 := c receiver. |
658 c := c sender. |
658 ((ex1 class == self class) |
659 (c notNil and:[c receiver == ex1]) ifTrue:[ |
659 or:[ex1 species == self species]) ifTrue:[ |
660 c := c sender. |
660 c := c sender. |
661 c notNil ifTrue:[ |
661 (c notNil and:[c receiver == ex1]) ifTrue:[ |
662 "/ the common case (really ?) first |
662 c := c sender. |
663 (c receiver == theSignal) ifTrue:[ |
663 c notNil ifTrue:[ |
664 (c selector startsWith:'raise') ifTrue:[ |
664 |
665 h := ex1 handlerContext. |
665 "/ the common case (really ?) first |
666 h notNil ifTrue:[ |
666 ((raiseReceiver := c receiver) == theSignal) ifTrue:[ |
667 activeHandlers isNil ifTrue:[ |
667 (c selector startsWith:'raise') ifTrue:[ |
668 activeHandlers := OrderedCollection new |
668 h := ex1 handlerContext. |
669 ]. |
669 h notNil ifTrue:[ |
670 |
670 activeHandlers isNil ifTrue:[ |
671 lastHandler := h. |
671 activeHandlers := OrderedCollection new |
672 activeHandlers add:lastHandler. |
672 ]. |
673 inHandler := true. |
673 |
674 c := lastHandler. |
674 lastHandler := h. |
675 "/ 'skip over active handler: ' print. c displayString printCR. |
675 activeHandlers add:lastHandler. |
676 ] |
676 inHandler := true. |
677 ] |
677 c := lastHandler. |
678 ] ifFalse:[ |
678 ] |
679 c receiver isSignal ifTrue:[ |
679 ] |
680 (c selector startsWith:'raise') ifTrue:[ |
680 ] ifFalse:[ |
681 h := ex1 handlerContext. |
681 raiseReceiver isSignal ifTrue:[ |
682 h notNil ifTrue:[ |
682 (c selector startsWith:'raise') ifTrue:[ |
683 (h receiver accepts:theSignal) ifTrue:[ |
683 h := ex1 handlerContext. |
684 |
684 h notNil ifTrue:[ |
685 activeHandlers isNil ifTrue:[ |
685 (h receiver accepts:theSignal) ifTrue:[ |
686 activeHandlers := OrderedCollection new |
686 |
687 ]. |
687 activeHandlers isNil ifTrue:[ |
688 lastHandler := h. |
688 activeHandlers := OrderedCollection new |
689 activeHandlers add:lastHandler. |
689 ]. |
690 inHandler := true. |
690 lastHandler := h. |
691 c := lastHandler. |
691 activeHandlers add:lastHandler. |
692 "/ 'skip2 over active handler: ' print. h displayString printCR. |
692 inHandler := true. |
693 ] |
693 c := lastHandler. |
694 ] |
694 ] |
695 ] |
695 ] |
696 ] |
696 ] |
697 ] |
697 ] |
698 ] |
698 ] |
699 ] |
699 ] |
700 ]. |
700 ] |
701 ]. |
701 ]. |
702 c := c sender. |
702 c := c sender. |
|
703 ] |
703 ]. |
704 ]. |
704 |
705 |
|
706 "/ now, start searching for a handler, |
|
707 "/ start search above the last active handler |
|
708 |
705 lastHandler notNil ifTrue:[ |
709 lastHandler notNil ifTrue:[ |
706 "/ 'skip over last active handler: ' print. lastHandler displayString printCR. |
710 con := lastHandler sender. |
707 con := lastHandler sender. |
|
708 ]. |
711 ]. |
709 |
712 |
710 any := false. |
713 any := false. |
711 [con notNil] whileTrue:[ |
714 [con notNil] whileTrue:[ |
712 con isBlockContext ifFalse:[ |
715 con isBlockContext ifFalse:[ |
713 |
716 |
714 "/ new behavior: |
717 sel := con selector. |
715 (activeHandlers notNil |
718 |
716 and:[activeHandlers includesIdentical:con]) ifTrue:[ |
719 ((sel == #'handle:do:') |
717 'skip activeHandler: ' print. con displayString printCR. |
720 or:[((sel == #'handle:from:do:') |
718 |
721 and:[(con argAt:2) == originator])]) ifTrue:[ |
719 ] ifFalse:[ |
722 |
720 sel := con selector. |
723 "/ new behavior: |
721 |
724 (activeHandlers notNil |
722 ((sel == #'handle:do:') |
725 and:[activeHandlers includesIdentical:con]) ifTrue:[ |
723 or:[((sel == #'handle:from:do:') |
726 'skip activeHandler: ' print. con displayString printCR. |
724 and:[(con argAt:2) == originator])]) ifTrue:[ |
727 |
725 " |
728 ] ifFalse:[ |
726 if this is the Signal>>handle:do: context |
729 " |
727 or a SignalSet>>handle:do: context with self in it, |
730 if this is the Signal>>handle:do: context |
728 call the handler |
731 or a SignalSet>>handle:do: context with self in it, |
729 " |
732 call the handler |
730 (con receiver accepts:signal) ifTrue:[ |
733 " |
731 "call the handler" |
734 (con receiver accepts:signal) ifTrue:[ |
732 |
735 "call the handler" |
733 conArg1 := con argAt:1. |
736 |
734 |
737 conArg1 := con argAt:1. |
735 handlerContext := con. |
738 |
736 any := true. |
739 handlerContext := con. |
737 |
740 any := true. |
738 self doCallHandler:conArg1. |
741 |
739 |
742 self doCallHandler:conArg1. |
740 "if the handler rejects, we arrive here" |
743 |
741 "continue search for another handler" |
744 "if the handler rejects, we arrive here" |
742 rejected := true. |
745 "continue search for another handler" |
743 ]. |
746 rejected := true. |
744 ] |
747 ]. |
745 ] |
748 ] |
746 ]. |
749 ] |
747 con := con sender |
750 ]. |
|
751 con := con sender |
748 ]. |
752 ]. |
749 |
753 |
750 activeHandlers := nil. |
754 activeHandlers := nil. |
751 |
|
752 "/ (inHandler "and:[rejected ~~ true]") ifTrue:[ |
|
753 "/ " |
|
754 "/ mhmh - an error while in a handler |
|
755 "/ here, we do not fall back to the noHandlerSignal/staticHandler |
|
756 "/ (makes debugging easier) |
|
757 "/ |
|
758 "/ Should we ? |
|
759 "/ " |
|
760 "/ ((signal == RecursiveExceptionSignal) |
|
761 "/ or:[RecursiveExceptionSignal isNil]) ifTrue:[ |
|
762 "/ " |
|
763 "/ ... either while handling RecursiveExceptionSignal |
|
764 "/ or at startup when RecursiveExceptionSignal is not yet |
|
765 "/ created - |
|
766 "/ - go immediately into the debugger. |
|
767 "/ " |
|
768 "/ ^ self enterDebuggerWith:self |
|
769 "/ message:'recursive signal raise' |
|
770 "/ ]. |
|
771 "/ ^ RecursiveExceptionSignal |
|
772 "/ raiseRequestWith:self |
|
773 "/ errorString:('recursive signal raise: (' , errorString , ')') |
|
774 "/ ]. |
|
775 |
755 |
776 " |
756 " |
777 we arrive here, if either no handler was found, or none of the |
757 we arrive here, if either no handler was found, or none of the |
778 handlers did a return (i.e. every handler rejected or fell through). |
758 handlers did a return (i.e. every handler rejected or fell through). |
779 " |
759 " |
780 " |
760 " |
781 try per signal handler |
761 try per signal handler |
782 " |
762 " |
783 (block := signal handlerBlock) isNil ifTrue:[ |
763 (block := signal handlerBlock) isNil ifTrue:[ |
784 "/ |
764 "/ |
785 "/ if its a querySignal, ignore it |
765 "/ if its a querySignal, ignore it |
786 "/ |
766 "/ |
787 signal isQuerySignal ifTrue:[^ nil]. |
767 signal isQuerySignal ifTrue:[^ nil]. |
788 |
768 |
789 "/ |
769 "/ |
790 "/ if it is not the NoHandlerSignal, raise it ... |
770 "/ if it is not the NoHandlerSignal, raise it ... |
791 "/ passing the receiver as parameter. |
771 "/ passing the receiver as parameter. |
792 "/ |
772 "/ |
793 signal ~~ (noHandlerSignal := Signal noHandlerSignal) ifTrue:[ |
773 signal ~~ (noHandlerSignal := Signal noHandlerSignal) ifTrue:[ |
794 noHandlerSignal notNil ifTrue:[ |
774 noHandlerSignal notNil ifTrue:[ |
795 any ifTrue:[ |
775 any ifTrue:[ |
796 msg := 'unhandled (rejected)' |
776 msg := 'unhandled (rejected)' |
797 ] ifFalse:[ |
777 ] ifFalse:[ |
798 msg := 'unhandled' |
778 msg := 'unhandled' |
799 ]. |
779 ]. |
800 msg := msg , ' exception: (' , errorString , ')'. |
780 msg := msg , ' exception: (' , errorString , ')'. |
801 ^ noHandlerSignal |
781 ^ noHandlerSignal |
802 raiseRequestWith:self |
782 raiseRequestWith:self |
803 errorString:msg |
783 errorString:msg |
804 in:self suspendedContext |
784 in:self suspendedContext |
805 ]. |
785 ]. |
806 "/ |
786 "/ |
807 "/ mhmh - an error during early startup; noHandlerSignal is |
787 "/ mhmh - an error during early startup; noHandlerSignal is |
808 "/ not yet defined. |
788 "/ not yet defined. |
809 "/ |
789 "/ |
810 ^ MiniDebugger enterWithMessage:errorString |
790 ^ MiniDebugger enterWithMessage:errorString |
811 ]. |
791 ]. |
812 |
792 |
813 " |
793 " |
814 mhmh - smells like trouble - there is no handler and |
794 mhmh - smells like trouble - there is no handler and |
815 no per-signal handler block. |
795 no per-signal handler block. |
816 Look for either a per-process emergencyHandlerBlock |
796 Look for either a per-process emergencyHandlerBlock |
817 or the global emergencyHandler (from Exception) ... |
797 or the global emergencyHandler (from Exception) ... |
818 " |
798 " |
819 Processor notNil ifTrue:[ |
799 Processor notNil ifTrue:[ |
820 "care for signal during startup (Processor not yet created)" |
800 "care for signal during startup (Processor not yet created)" |
821 block := Processor activeProcess emergencySignalHandler. |
801 block := Processor activeProcess emergencySignalHandler. |
822 ]. |
802 ]. |
823 block isNil ifTrue:[ |
803 block isNil ifTrue:[ |
824 block := Exception emergencyHandler. |
804 block := Exception emergencyHandler. |
825 block isNil ifTrue:[ |
805 block isNil ifTrue:[ |
826 "care for error during startup (Exception not yet initialized)" |
806 "care for error during startup (Exception not yet initialized)" |
827 ^ MiniDebugger enterWithMessage:errorString |
807 ^ MiniDebugger enterWithMessage:errorString |
828 ]. |
808 ]. |
829 ]. |
809 ]. |
830 ]. |
810 ]. |
831 "... and call it" |
811 "... and call it" |
832 ^ block value:self. |
812 ^ block value:self. |
833 |
813 |
834 "Created: 12.5.1996 / 15:09:39 / cg" |
814 "Created: 12.5.1996 / 15:09:39 / cg" |