Exception handling

C. David Shaffer cdshaffer at acm.org
Fri Sep 14 15:48:17 UTC 2007


"Here are some musings on exception handling and a method I'm playing 
with.  I'd appreciate the eyes of someone more versed in this.

ensure block runs after handler block has returned (but this is not a 
resumable error)"
[
    [1/0] ensure: [Transcript show: 'ensure'; cr]
] on: Error do: [:ex | Transcript show: 'handler'; cr]

"produces:

handler
ensure"


"...makes sense for Notifications since we might 'ex resume: someValue'"
[
    [Notification signal: 'yes'] ensure: [Transcript show: 'ensure'; cr].
] on: Notification do: [:ex | Transcript show: 'handler'; cr]

"what if we retry the block?  works as expected...ensure block runs 
before block retried."
retried := false.
[
    [1/0] ensure: [Transcript show: 'ensure'; cr]
] on: Error do: [:ex | Transcript show: 'handler'; cr.
    retried ifFalse: [retried := true. ex retry]]

"produces

handler
ensure
handler
ensure"

"OK...consistency is nice but what if our handler really doesn't plan or 
can't resume an exception.
I propose:"

[
    [1/0] ensure: [Transcript show: 'ensure'; cr]
] on: Error unwindAndDo: [:ex | Transcript show: 'handler'; cr.
    retried ifFalse: [retried := true. ex retry]]

"which produces

ensure
handler


The on:unwindAndDo: semantics are important if the handler needs to 
access a resource protected by a mutex and used in the protected block.  
So:"

mutex := Semaphore forMutualExclusion.
[
    mutex critical: [Error signal: 'I am bad']
] on: Error unwindAndDo: [mutex critical: [Transcript show: 'handler'; cr]]

"
produces

handler

rather than deadlocking as it would with on:do:

Here is a hackish implementation:

BlockContext>>on: exception unwindAndDo: handler
    ^self on: exception do: [:ex |
          (ex instVarNamed: #signalContext) unwindTo: (ex instVarNamed: 
#handlerContext).
        handler value]


I'm driving without a map here...does anyone else find this to be a 
useful exception handling pattern?  Has this been hashed over before?  
Is the above code horribly evil (besides the obvious intrusion of 
instVarNamed:)?

"

David




More information about the Squeak-dev mailing list