Skip to main content
Engineering LibreTexts

12.6: Specifying Which Exceptions Will Be Handled

  • Page ID
    43734
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \) \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)\(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\) \(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\)\(\newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    In Smalltalk, exceptions are, of course, objects. In Pharo, an exception is an instance of an exception class which is part of a hierarchy of exception classes. For example, because the exceptions FileDoesNotExistException, FileExistsException and CannotDeleteFileException are special kinds of FileStreamException, they are represented as subclasses of FileStreamException, as shown in Figure 13.5.1. This notion of “specialization” lets us associate an exception handler with a more or less general exceptional situation. Allowing us to write different expressions depending on the level of granularity we want:

    [...]on:Errordo:[...] or
    [ ... ] on: FileStreamException do: [ ... ] or
    [ ... ] on: FileDoesNotExistException do: [ ... ]
    

    The class FileStreamException adds information to class Exception to characterize the specific abnormal situation it describes. Specifically, FileStreamException defines the fileName instance variable, which contains the name of the file that signaled the exception. The root of the exception class hierarchy is Exception, which is a direct subclass of Object.

    Two key messages are involved in exception handling: on:do:, which, as we have already seen, is sent to blocks to set an exception handler, and signal, which is sent to subclasses of Exception to signal that an exception has occurred.

    Catching sets of exceptions

    So far, we have always used on:do: to catch just a single class of exception. The handler will only be invoked if the exception signaled is a sub-instance of the specified exception class. However, we can imagine situations where we might like to catch multiple classes of exceptions. This is easy to do. Just specify a list of classes separated by commas as shown in the following example.

    result := [ Warning signal . 1/0 ]
        on: Warning, ZeroDivide
        do: [:ex | ex resume: 1 ].
    result    →    1
    

    If you are wondering how this works, have a look at the implementation of Exception class»,

    Exception class», anotherException
        "Create an exception set."
        ^ExceptionSet new add: self; add: anotherException; yourself 
    

    The rest of the magic occurs in the class ExceptionSet, which has a surprisingly simple implementation.

    Object subclass: #ExceptionSet
        instanceVariableNames: 'exceptions'
        classVariableNames: ''
        poolDictionaries: ''
        category: 'Exceptions-Kernel'
    
    ExceptionSet»initialize
        super initialize.
        exceptions := OrderedCollection new
    
    ExceptionSet», anException
        self add: anException.
        ^self
    
    ExceptionSet»add: anException
        exceptions add: anException
    
    ExceptionSet»handles: anException
        exceptions do: [:ex | (ex handles: anException) ifTrue: [^true]].
        ^false
    

    The message handles: is also defined on a single exception and returns whether the receiver handles the exception.


    This page titled 12.6: Specifying Which Exceptions Will Be Handled is shared under a CC BY-SA 3.0 license and was authored, remixed, and/or curated by Alexandre Bergel, Damien Cassou, Stéphane Ducasse, Jannik Laval (Square Bracket Associates) via source content that was edited to the style and standards of the LibreTexts platform; a detailed edit history is available upon request.