GenericException.st
branchjv
changeset 19811 65fec19facb0
parent 19635 875eb54afd2c
parent 19776 31fa179f48bf
child 20131 4118d61ddba0
equal deleted inserted replaced
19707:8e312f358d84 19811:65fec19facb0
       
     1 "{ Encoding: utf8 }"
       
     2 
     1 "
     3 "
     2  COPYRIGHT (c) 1993 by Claus Gittinger
     4  COPYRIGHT (c) 1993 by Claus Gittinger
     3 	      All Rights Reserved
     5 	      All Rights Reserved
     4 
     6 
     5  This software is furnished under a license and may be used
     7  This software is furnished under a license and may be used
    45 !
    47 !
    46 
    48 
    47 documentation
    49 documentation
    48 "
    50 "
    49     Note:
    51     Note:
    50 	The instance based Signal framework is being replaced by
    52         The instance based Signal framework is being replaced by
    51 	class based exceptions.
    53         class based exceptions.
    52 	I.e. what used to be instances of Signal/QuerySignal is beeing
    54         I.e. what used to be instances of Signal/QuerySignal is being
    53 	rewritten into subclasses of Exception/Error/Query and Warning.
    55         rewritten into subclasses of Exception/Error/Query and Warning.
    54 	Although the functionality is basically unchanged, the new
    56         Although the functionality is basically unchanged, the new
    55 	class based exceptions are easier to instanciate (no need for
    57         class based exceptions are easier to instanciate (no need for
    56 	creation in a classes initialize method), easier to use (no real
    58         creation in a classes initialize method), easier to use (no real
    57 	need for SIgnal-constant accessors) and allow for easier parameter
    59         need for SIgnal-constant accessors) and allow for easier parameter
    58 	passing (not only a single parameter, but allows for individual
    60         passing (not only a single parameter, but allows for individual
    59 	exception subclasses to add additional state).
    61         exception subclasses to add additional state).
    60 
    62 
    61     GenericException and its subclasses implement the same protocol as Signal.
    63     GenericException and its subclasses implement the same protocol as Signal.
    62     So class based exceptions may be implemented as subclasses of GenericException.
    64     So class based exceptions may be implemented as subclasses of GenericException.
    63 
    65 
    64     Normally all exceptions are subclasses of Exception. Exceptions, that are
    66     Normally all exceptions are subclasses of Exception. Exceptions, that are
    67 
    69 
    68     Instances of Exception are passed to a Signal handling block as argument.
    70     Instances of Exception are passed to a Signal handling block as argument.
    69     The handler block may perform various actions by sending corresponding messages
    71     The handler block may perform various actions by sending corresponding messages
    70     to the exception object. The following actions are possible:
    72     to the exception object. The following actions are possible:
    71 
    73 
    72 	reject          - don't handle this signal;
    74         reject          - don't handle this signal;
    73 			  another handler will be searched for,
    75                           another handler will be searched for,
    74 			  upper in the calling hierarchy
    76                           upper in the calling hierarchy
    75 
    77 
    76 	proceed         - return from the Signal>>raise, with nil as value
    78         proceed         - return from the Signal>>raise, with nil as value
    77 
    79 
    78 	proceedWith:val - same, but return val from Signal>>raise
    80         proceedWith:val - same, but return val from Signal>>raise
    79 
    81 
    80 	return          - return from the Signal>>handle:do:, with nil as value
    82         return          - return from the Signal>>handle:do:, with nil as value
    81 
    83 
    82 	returnWith:val  - same, but return val from Signal>>handle:do:
    84         returnWith:val  - same, but return val from Signal>>handle:do:
    83 			  (this is also the handler's default,
    85                           (this is also the handler's default,
    84 			   if it falls through; taking the handlerBlocks value
    86                            if it falls through; taking the handlerBlocks value
    85 			   as return value)
    87                            as return value)
    86 
    88 
    87 	restart         - restart the Signal>>handle:do:, after repairing
    89         restart         - restart the Signal>>handle:do:, after repairing
    88 
    90 
    89     Via the Exception object, the handler can also query the state of execution:
    91     Via the Exception object, the handler can also query the state of execution:
    90     where the Signal was raised, where the handler is, the signal which caused
    92     where the Signal was raised, where the handler is, the signal which caused
    91     the error and the messageText passed when the signal was raised. Also, an optional
    93     the error and the messageText passed when the signal was raised. Also, an optional
    92     parameter can be passed - the use is signal specific.
    94     parameter can be passed - the use is signal specific.
    93 
    95 
    94     [instance variables:]
    96     [instance variables:]
    95 	signal           <Signal>     the signal which caused the exception
    97         signal           <Signal>     the signal which caused the exception
    96 
    98 
    97 	parameter        <Object>     a parameter (if any) which was passed when raising
    99         parameter        <Object>     a parameter (if any) which was passed when raising
    98 				      the signal (only if raised with #raiseWith:aParameter)
   100                                       the signal (only if raised with #raiseWith:aParameter)
    99 
   101 
   100 	messageText      <String>     an messageText
   102         messageText      <String>     an messageText
   101 				      (usually the signals own messageText, but sometimes
   103                                       (usually the signals own messageText, but sometimes
   102 				       changed explicitely in #raiseWith:errorString:)
   104                                        changed explicitely in #raiseWith:errorString:)
   103 
   105 
   104 	suspendedContext <Context>    the context in which the raise occured
   106         suspendedContext <Context>    the context in which the raise occured
   105 
   107 
   106 	handlerContext   <Context>    the context of the handler (if any)
   108         handlerContext   <Context>    the context of the handler (if any)
   107 
   109 
   108     In case of an unhandled signal raise, Exceptions EmergenyHandler will be evaluated.
   110     In case of an unhandled signal raise, Exceptions EmergenyHandler will be evaluated.
   109     The default emergeny handler will enter the debugger.
   111     The default emergeny handler will enter the debugger.
   110 
   112 
   111     For applications, which do not want Debuggers to come up, other handlers are
   113     For applications, which do not want Debuggers to come up, other handlers are
   112     possible.
   114     possible.
   113     For example, to get the typical C++ behavior, use:
   115     For example, to get the typical C++ behavior, use:
   114 	Exception emergencyHandler:[:ex | Smalltalk exitWithCoreDump]
   116         Exception emergencyHandler:[:ex | Smalltalk exitWithCoreDump]
   115 
   117 
   116 
   118 
   117     Raising:
   119     Raising:
   118 	two different raising messages are to be used,
   120         two different raising messages are to be used,
   119 	depending on whether the exception is proceedable or not
   121         depending on whether the exception is proceedable or not
   120 
   122 
   121 	For some stupid reason, someone decided that the raise-code checks if
   123         For some stupid reason, someone decided that the raise-code checks if
   122 	the raising messages matches to what the signal thinks is its proceedability.
   124         the raising messages matches to what the signal thinks is its proceedability.
   123 	(i.e. not only do both the sender and the signal itself specify proceedability,
   125         (i.e. not only do both the sender and the signal itself specify proceedability,
   124 	 this is checked by the raise code and a warning is generated if there is a mismatch)
   126          this is checked by the raise code and a warning is generated if there is a mismatch)
   125 	This used to be even worse (WrongProceedabilityError), but we relaxed this to
   127         This used to be even worse (WrongProceedabilityError), but we relaxed this to
   126 	a message sent to stderr.
   128         a message sent to stderr.
   127 
   129 
   128 	That means, that PROCEEDABLE signals must be raised with:
   130         That means, that PROCEEDABLE signals must be raised with:
   129 	    raiseRequest
   131             raiseRequest
   130 	and NON-PROCEEDABLE signals must be raised with:
   132         and NON-PROCEEDABLE signals must be raised with:
   131 	    raise
   133             raise
   132 
   134 
   133 	If you dont know/care as a raiser, you can use
   135         If you dont know/care as a raiser, you can use
   134 	    raiseSignal
   136             raiseSignal
   135 	which checks for proceedability and sends the appropriate message.
   137         which checks for proceedability and sends the appropriate message.
   136 	(sigh)
   138         (sigh)
   137 
   139 
   138     all of the 3 messages above come in various flavours:
   140     all of the 3 messages above come in various flavours:
   139 	raiseXXX                - do not pass any additional parameter;
   141         raiseXXX                - do not pass any additional parameter;
   140 				  default messageText
   142                                   default messageText
   141 
   143 
   142 	raiseXXXWith:           - pass additional parameter;
   144         raiseXXXWith:           - pass additional parameter;
   143 				  default messageText
   145                                   default messageText
   144 
   146 
   145 	raiseXXXErrorString:    - do not pass any additional parameter;
   147         raiseXXXErrorString:    - do not pass any additional parameter;
   146 				  given errorString
   148                                   given errorString
   147 
   149 
   148 	raiseXXXWith:errorString:
   150         raiseXXXWith:errorString:
   149 				- pass any additional parameter;
   151                                 - pass any additional parameter;
   150 				  AND given errorString
   152                                   AND given errorString
   151 
   153 
   152 
   154 
   153     [see also:]
   155     [see also:]
   154 	Signal  SignalSet QuerySignal
   156         Signal  SignalSet QuerySignal
   155 	Context Block
   157         Context Block
   156 	Object DebugView
   158         Object DebugView
   157 	(``Exception handling and signals'': programming/exceptions.html)
   159         (``Exception handling and signals'': programming/exceptions.html)
   158 
   160 
   159     [author:]
   161     [author:]
   160 	Claus Gittinger
   162         Claus Gittinger
   161 "
   163 "
   162 !
   164 !
   163 
   165 
   164 examples
   166 examples
   165 "
   167 "
   221 
   223 
   222     <resource: #skipInDebuggersWalkBack>
   224     <resource: #skipInDebuggersWalkBack>
   223 
   225 
   224     self raiseErrorString:messageText
   226     self raiseErrorString:messageText
   225 ! !
   227 ! !
   226 
       
   227 
   228 
   228 !GenericException class methodsFor:'accessing'!
   229 !GenericException class methodsFor:'accessing'!
   229 
   230 
   230 errorString
   231 errorString
   231     "#errorString is deprecated, use description instead"
   232     "#errorString is deprecated, use description instead"
   549 
   550 
   550     "Created: / 23-07-1999 / 14:07:17 / stefan"
   551     "Created: / 23-07-1999 / 14:07:17 / stefan"
   551     "Modified: / 10-08-2010 / 09:30:42 / cg"
   552     "Modified: / 10-08-2010 / 09:30:42 / cg"
   552 !
   553 !
   553 
   554 
       
   555 raiseAsQuery
       
   556     "utility to avoid code duplication.
       
   557      raise the exception as a query. This means, that if it is unhandled,
       
   558      a default value is returned (i.e. an implicit resume).
       
   559      Return the handler's value (if there is one), or the default value, if not.
       
   560      Invoking the handler is exactly the functionality of Signal>>raiseRequest,
       
   561      but we can do it faster here (avoiding the construction of an exception instance)."
       
   562 
       
   563     |con signal ret|
       
   564 
       
   565     self isQuerySignal ifFalse:[ self error:'this may only be used by queries' ].
       
   566 
       
   567     con := Context findFirstSpecialHandle:true raise:false.
       
   568     [con notNil] whileTrue:[
       
   569         (con selector == #answer:do:) ifTrue:[ 
       
   570             signal := con receiver.
       
   571             signal == self ifTrue:[
       
   572                 ret := con argAt:1.
       
   573                 con := nil.
       
   574                 ^ ret
       
   575             ].
       
   576             signal isNil ifTrue:[
       
   577                 self error:'nil receiver in #answer:do: - send'.
       
   578             ].
       
   579             (signal accepts:self) ifTrue:[
       
   580                 ret := con argAt:1.
       
   581                 con := nil.
       
   582                 ^ ret
       
   583             ].
       
   584         ] ifFalse:[
       
   585             "ask the the receiver of the #handle:do: or #on:do: or whatever- message for the handler.
       
   586              nil is returned, if the signal is not accepted"
       
   587             |r|
       
   588             r := con receiver.     "receiver of #handle:do: or #on:do:"
       
   589             (r notNil and:[(r handlerForSignal:self
       
   590                                  context:con
       
   591                                  originator:thisContext sender homeReceiver) notNil]
       
   592             ) ifTrue:[
       
   593                 "there is another handler block, maybe it will return the answer.
       
   594                  Call it via raiseRequest"
       
   595                 con := nil.
       
   596                 ^ here raiseRequest  "/ <- notice the here, to avoid recursion due
       
   597                                      "/ to redefined raiseRequest in Query
       
   598             ].
       
   599         ].
       
   600         con := con findSpecialHandle:true raise:false.
       
   601     ].
       
   602 
       
   603     "/ no handler found - return the default value
       
   604     ^ self defaultAnswer
       
   605 
       
   606     "Modified: / 15-06-1998 / 21:27:37 / cg"
       
   607     "Modified: / 25-07-1999 / 23:15:16 / stefan"
       
   608     "Modified: / 11-03-2015 / 11:26:45 / sr"
       
   609 !
       
   610 
   554 raiseErrorString:aString
   611 raiseErrorString:aString
   555     "raise a signal nonproceedable.
   612     "raise a signal nonproceedable.
   556      The argument is used as messageText."
   613      The argument is used as messageText."
   557 
   614 
   558     <context: #return>
   615     <context: #return>