You construct exception handlers by sending the message when:do: to a block. You can install multiple handlers simultaneously by using repeated forms of when:do: (that is, when:do:when:do:, when:do:when:do:when:do:, and so on) for up to five handlers. Because the handlers are tried in order, more general handlers should be placed later in the list. You can use nesting to allow more than five handlers if absolutely required.
The first argument to when:do: is an instance of class ExceptionalEvent. The second argument is a one-argument handler block that is passed the instance of Signal that describes the exception.
When an exception is signaled, the most recent when:do: matching the exception is evaluated first. When a when:do: message is found with either the exception or a more general exception (one of the exception's ancestors) as the when argument, its handlerBlock is run.
Within the handler block, the following methods can be sent to an instance of Signal:
Assuming that ThatException is a global variable, an application could have the following code:
"Initialization code."
(ThatException := ExAll newChild)
description: 'That exception occurred.'.
thatMethod
"Answer true if thatTest completes without error,
otherwise signal ThatException."
self thatTest failed
ifTrue: [ ThatException signal ].
^true
anyMethod
"The application can then do something like the following.
Answer true if thatMethod completes without exception,
and false otherwise."
^[ self thatMethod ]
when: ThatException
do: [:signal |
"Handle the exception in some way: increment a counter,
print a message, fix a problem, ... and then exit the handler."
signal exitWith: false].
Note that "dropping off the end" of a handler block is equivalent to sending
resumeWith: (Association key: #resume value: valueOfTheBlock
where valueOfTheBlock is the value of the handler block.