Exception Handling

Boris Gaertner Boris.Gaertner at gmx.net
Mon Mar 20 21:15:24 UTC 2006


"Zulq Alam" <zulq at orange.net> wrote:

> Hello,
>
> I'm a bit confused about exception handling, perhaps you can help please?
>
> If I have a method #foo and #foo can signal two errors FooError and
> UnrelatedToFooError how do I handle both errors using #on:do: without
> having something like...
>
> [someObject foo]
>     on: Error
>     do: [:error | (error class = FooError) ifTrue: ["do something
> specific to FooError"].
>           (error class = UnrelatedToFooError) ifTrue: ["do something
> specific to UnrelatedToFooError"]].
>
> In Java I would do something like
>
> try {
>     somObject.foo();
> }
> catch (FooError e) {
>     // do something specific to FooError
> }
> catch (UnrelatedToFooError e) {
>     // do something specific to UnrelatedToFooError
> }
>
> Even if under the hood the same is happening this seems to take care of
> some very common code.
>
> Is there something in Smalltalk/Squeak will provide something similar?
>
Not exactly. The
      try {...} catch{...} catch {...} ...
is similar to the well-known case-statement in that it enumerates
a variable number of cases. This does not fit into the message
syntax that does not allow for a variable number of message
arguments.

Given this restriction it is the correct solution to let the
handler check the class of the exception.

There is however one peculiarity that I should mention:

The on: Error do: <handler>

catches all exception that are represented as instances of Error
or as instances of subclasses of Error.When you use this construct
to handle only exceptions of types  FooError  and UnrelatedToFooError,
you may have to propagate (resignal) all exceptions that you do not want
to handle.

You can however set up a handler that does not catch all Errors,
but only the exceptions you are intersted in:

 /* example 1 */
 [someObject foo]
   on: FooError, UnrelatedToFooError
   do: [ error |
         (error class = FooError)
            ifTrue: ["do something specific to FooError"].
        (error class = UnrelatedToFooError)
          ifTrue: ["do something specific to UnrelatedToFooError"]
       ].

The message  #, is defined in the class protocol of classes
Exception and ExceptionSet. It is used to group
exceptions into exception sets.


I think you can even write:

/* example 2*/
 [someObject foo]
   on: FooError, UnrelatedToFooError
   do: [ error |
          error class caseOf:
             { [FooError] ->  ["do something specific to FooError"].
                [UnrelatedToFooError] -> ["do something specific to
UnrelatedToFooError"]
             }.
       ].

Please have a look at Object >> caseOf:  if you think this
may be useful for you.

Note that there is a difference between example 1 and this
statement:

 [someObject foo]
   on: FooError, UnrelatedToFooError
   do: [ error |
         (error class isKindOf: FooError)
            ifTrue: ["do something specific to FooError"].
        (error class isKindOf: UnrelatedToFooError)
          ifTrue: ["do something specific to UnrelatedToFooError"]
       ].

With this statement you can handle also exceptions that
are represented by subclasses of either FooError or
UnrelatedToFooErrror.

Example 1 and example 2 are equivalent it that they both handle
only exceptions of classes  FooError, UnrelatedToFooError.


This is not exactly what you hope to read, but
it may illustrate some less frequently explained aspects
of exceptions handling.

Greetings,
Boris




More information about the Squeak-dev mailing list