10.1 Inspecting the Unexpected

We have seen how various exceptional situations cause the appearance of a debugger window. Indeed, Exceptions are also objects which remember their context and can present it. Above, we have seen how to generate MessageNotUnderstood and ZeroDivide Exception instances.

This is another area where the actual mechanics are complex, but the basic ideas are simple.

Exception instances, being objects, also have classes. The BlockClosure has a method category exceptions which gathers some handy methods which allow one to ensure: cleanup or capture and use exceptions (on:do: and friends).

FileEntry>>readStreamDo: blockWithArg 
  "Raise FileDoesNotExistException if not found."
  | stream result |
  stream := self readStream.
  [ result := blockWithArg value: stream ]
	ensure: [ stream ifNotNil: [ :s | s close ]].
  ^ result

Example 10.1: Ensure a FileStream is closed

Exceptions are created and signaled. Let’s make one and look at it.

ch10-01-ZeroDivide

Figure 10.1: Inspecting a ZeroDivide instance

Again, we can use an Inspector on any object, and Exceptions are no exception! Now you know how to capture one when you need to.

Exceptions, like MorphicEvents are a change, an exception, to typical control flow.

We noted above the special pseudo-variable, thisContext. Signalling an exception captures this.

Exception>>signal

  ^ self signalIn: thisContext

Example 10.2: Capture thisContext

Just as Smalltalk code has special view windows which we call Browsers, Exceptions have an enhanced viewer we call the Debugger. Let us look at how to use this very useful viewer.