This corner case is triggered by this simple snippet
[[self error: 'abc'] on: Exception do: [ :ex | 'bad' printNl ] on: Error do: [ :ex | ex pass ]] on: Error do: [ :ex | 'ok' printNl ] The second exception handler is triggered and passes to the outer exception handler. However, the first handler (the one for Exception) is never disabled, so #pass triggers that exception handler instead of the outer one! This is easily fixed -- even if only the "best" handler is chosen, all of them should be disabled. Paolo commit f4c89de35854ee944cdec488b68c45003885369c Author: Paolo Bonzini <[hidden email]> Date: Sun Jun 1 19:21:42 2008 +0200 fix weird case of nested exception handlers and #pass 2008-06-01 Paolo Bonzini <[hidden email]> * kernel/BlkClosure.st: Fix weird case of #on:do:on:do:on:do:. * tests/exceptions.st: Add test case. * tests/exceptions.ok: Regenerate. diff --git a/ChangeLog b/ChangeLog index b060faf..6b1052f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2008-06-01 Paolo Bonzini <[hidden email]> + * kernel/BlkClosure.st: Fix weird case of #on:do:on:do:on:do:. + * tests/exceptions.st: Add test case. + * tests/exceptions.ok: Regenerate. + +2008-06-01 Paolo Bonzini <[hidden email]> + * kernel/URL.st: Fix redirects including a GET query. Add #contents and #readStream. diff --git a/kernel/BlkClosure.st b/kernel/BlkClosure.st index 6e7bca3..2b635bf 100644 --- a/kernel/BlkClosure.st +++ b/kernel/BlkClosure.st @@ -70,27 +70,27 @@ creation of Processes from blocks.'> [(activeHandlers bitAt: i) = 1 ifTrue: ["Sorry, this handler is already active..." + nested := true] + ifFalse: + [activeHandlers := activeHandlers setBit: i. + goodness > bestGoodness + ifTrue: + [best := i. + bestGoodness := goodness]]]]]. - nested := true. - goodness := -1]]. - goodness > bestGoodness - ifTrue: - [best := i. - bestGoodness := goodness]]]. + context at: context numArgs + 1 put: activeHandlers. "Now instantiate the best handler we found" best isNil ifFalse: - [context at: context numArgs + 1 put: (activeHandlers setBit: best). - signal + [signal onDoBlock: context receiver handlerBlock: (context at: best + 1) onDoContext: context previousState: activeHandlers. #found] ifTrue: - [context at: context numArgs + 1 put: activeHandlers. - nested ifTrue: [#skip] ifFalse: [nil]]] + [nested ifTrue: [#skip] ifFalse: [nil]]] ] BlockClosure class >> numArgs: args numTemps: temps bytecodes: bytecodes depth: depth literals: literalArray [ diff --git a/tests/exceptions.ok b/tests/exceptions.ok index c54128e..5fbf15c 100644 --- a/tests/exceptions.ok +++ b/tests/exceptions.ok @@ -19,6 +19,11 @@ returned value is TextCollector new "<0>" Execution begins... +testPass (2)...passing...ok +returned value is TextCollector new "<0>" + +Execution begins... + testEnsure... error: Ignore this error passed returned value is nil diff --git a/tests/exceptions.st b/tests/exceptions.st index 377411e..4c06f5d 100644 --- a/tests/exceptions.st +++ b/tests/exceptions.st @@ -76,6 +76,18 @@ Eval [ ] Eval [ + "Test that passing disables all exception handlers in the #on:do: snippet." + + Transcript cr; show: 'testPass (2)...'. + [[self error: 'abc'] + on: Exception do: [ :ex | Transcript show: 'failed' ] + on: Error do: [ :ex | Transcript show: 'passing...'. ex pass ]] + on: Error do: [ :ex | Transcript show: 'ok' ]. + + Transcript cr +] + +Eval [ [ Transcript cr; show: 'testEnsure...'. self error: ' Ignore this error'] ensure: [Transcript show: 'passed'; cr] _______________________________________________ help-smalltalk mailing list [hidden email] http://lists.gnu.org/mailman/listinfo/help-smalltalk |
Free forum by Nabble | Edit this page |