Navigation:  Programming Cookbook > Exception Handling >

Catching Multiple Exceptions

Previous pageReturn to chapter overviewNext page

When one establishes an exception environment with #on:do: and one specifies s a class of exception to catch, then the handler will be evaluated when any exceptions are raised which are sub-instances of that class. Sometimes one may want to catch a group of exceptions that are not necessarily related by hierarchy, and this is where ExceptionSets can be used.

ExceptionsSets are normally constructed by specifying a comma-separated list of Exception classes, for example:

ExternalStructure>>safeAt: index

  "Answer the byte at the specified index in the receiver.

  If the index is outside the bounds of the buffer owned by the receiver,

  or not accessible in a referenced buffer, then answer 0."

  ^[contents at: index] on: BoundsError, GPFault do: [:ex | 0]

 

An ExceptionSet can contain as many classes of Exception as one wishes, and if any are the class, or a superclass, of an exception raised in the protected block, then the handler will be evaluated.

On other occasions, particularly on subsystem boundaries, we may need to handle a number of different possible exceptions separately. This is achieved with ExceptionHandlerSets, usually by using on of the #on:do:[on:do:]+ messages to BlockClosure. For example:

ExternalStructure>>safeAt: index

  "Answer the byte at the specified index in the receiver.

  If the index is outside the bounds of the buffer owned by the receiver,

  or not accessible in a referenced buffer, then answer 0."

  ^[contents at: index]

      on: BoundsError, GPFault do: [:ex | 0]

      on: Error do: [:ex | Notification signal: 'Unexpected error ', ex description. 0]

 

The more general classes of exception should be specified last, as any more specific classes/sets appearing later will otherwise not get an opportunity to handle any exceptions.

The base system includes messages for 1 to 4 separate exceptions and handlers, though more can be accommodated by adding more messages, or by manually constructing an ExceptionHandlerSet and passing it to BlockClosure>>onDo:. Browse BlockClosure>>on:do:on:do: to see how to build an ExceptionHandlerSet.