Skip to main content
Engineering LibreTexts

12.5: Error Codes — Don't Do This!

  • Page ID
    43733
  • \( \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}}\)

    Without exceptions, one (bad) way to handle a method that may fail to produce an expected result is to introduce explicit error codes as possible return values. In fact, in languages like C, code is littered with checks for such error codes, which often obscure the main application logic. Error codes are also fragile in the face of evolution: if new error codes are added, then all clients must be adapted to take the new codes into account. By using exceptions instead of error codes, the programmer is freed from the task of explicitly checking each return value, and the program logic stays uncluttered. Moreover, because exceptions are classes, as new exceptional situations are discovered, they can be subclassed; old clients will still work, although they may provide less-specific exception handling than newer clients.

    If Smalltalk did not provide exception-handling support, then the tiny example we saw in the previous section would be written something like this, using error codes:

    "Pseudo-code -- luckily Smalltalk does not work like this. Without the
    benefit of exception handling we must check error codes for each operation."
    source := 'log.txt'.
    destination := 'log-backup.txt'.
    success := 1. "define two constants, our error codes"
    failure := 0.
    fromStream := FileStream oldFileNamed: (FileSystem workingDirectory / source).
    fromStream ifNil: [
        UIManager default inform: 'Copy failed -- could not open', source.
        ^ failure "terminate this block with error code" ].
    toStream := FileStream newFileNamed: (FileSystem workingDirectory / destination).
    toStream ifNil: [
        fromStream close.
        UIManager default inform: 'Copy failed -- could not open', destination.
        ^ failure ].
    contents := fromStream contents.
    contents ifNil: [
        fromStream close.
        toStream close.
        UIManager default inform: 'Copy failed -- source file has no contents'.
        ^ failure ].
    result := toStream nextPutAll: contents.
    result ifFalse: [
        fromStream close.
        toStream close.
        UIManager default inform: 'Copy failed -- could not write to ', destination.
        ^ failure ].
    fromStream close.
    toStream close.
    ^ success.
    

    Part of the Pharo exception hierarchy.
    Figure \(\PageIndex{1}\): A small part of the Pharo exception hierarchy.

    What a mess! Without exception handling, we must explicitly check the result of each operation before proceeding to the next. Not only must we check error codes at each point that something might go wrong, but we must also be prepared to cleanup any operations performed up to that point and abort the rest of the code.


    This page titled 12.5: Error Codes — Don't Do This! 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.