Bug: 40815

Impact:

Product:
GemStone/S 64 Bit

Versions:
2.4.4, 2.3.1.6, 2.3.1, 2.3, 2.2.5.4, 2.2.5.3, 2.2.5.2, 2.2.5.1, 2.2.5, 2.2.4, 2.2.3, 2.2.2, 2.2.1, 2.2

Platform:
All

Fixed In:
2.4.4.2

ExceptionSets break exception handling

Passing an ExceptionSet, rather than an Exception, to an on:do: or try:on:do:
message, results in the exception not getting caught.

ExceptionSets are created when multiple exceptions are passed, for example:

[1 / 0 ]
  on: ZeroDivide, MessageNotUnderstood
  do: [ :ex | ... ].

Workaround:

file in the following:

category: 'ANSI support'
method: ExceptionSet
handlesCategory: anObject number: anInteger
     "This method may be overridden for ExceptionSelectors that are more discriminating.
     For example, one might want to trap all GemStoneError numbers in a certain
range."

     ^selectors anySatisfy: [:each | each handlesCategory: anObject number:
anInteger].
%
category: 'Exceptions'
method: ExceptionHandler
try: aBlock on: anExceptionSelector do: anotherBlock
     "anExceptionSelector is generally a subclass of ExceptionA or
     an ExceptionSet containing subclasses of ExceptionA"

     | protectedBlock |
     protectedBlock := aBlock.
     exceptionSelector := anExceptionSelector.
     returnBlock := [:value | ^value].
     gsException := Exception
          category: exceptionSelector errorCategoryToCatch
          number: exceptionSelector errorNumberToCatch
          do: [:ex :cat :num :args |
               "The following code can return from the #'on:do:' message by using the
returnBlock"
               self caughtEx: ex number: num cat: cat args: args handler: anotherBlock.
               "If we fall through, the result of the above expression will be returned
by the #'signal' message."
          ].
     gsException handler: self.
     [true] whileTrue: [
          | newBlock |
          (newBlock := self doTryBlock: protectedBlock) notNil ifTrue: [protectedBlock
:= newBlock].
     ].
%
category: 'Block Evaluation'
method: ExecutableBlock
on: selector do: action
     "Try to evaluate the receiver, and should an exception occur which is
matched
     by selector (normally a class object which is a subclass of ExceptionA
but can
     also be an ExceptionSet with subclasses of ExceptionA), evaluate the
     <monadicBlock>, action, passing it the exception instance as its argument.

     This method is replaced by AnsiMisc.gs"

     ^(Globals at: #'ExceptionHandler') new
          try: self
          on: selector
          do: action.
%
category: 'ANSI support'
classmethod: MessageNotUnderstood
handlesCategory: anObject number: anInteger

     ^anObject == GemStoneError and: [anInteger == 2010].
%
category: 'ANSI support'
classmethod: ZeroDivide
handlesCategory: anObject number: anInteger

     ^anObject == GemStoneError and: [anInteger == 2026].
%
category: 'Block Evaluation'
method: ExecutableBlock
on: selector do: action
     "Try to evaluate the receiver, and should an exception occur which is
matched
     by selector (normally a class object which is a subclass of ExceptionA
but can
     also be an ExceptionSet instance with subclasses of ExceptionA), evaluate
the
     <monadicBlock>, action, passing it the exception instance as its argument."

     ^ExceptionHandler new
          try: self
          on: selector
          do: action.
%