Next: Behind the scenes, Previous: Streams, Up: Tutorial
Up to this point of the tutorial, you used the original Smalltalk-80 error signalling mechanism:
check: num [ | c | c := history at: num ifAbsent: [ ^self error: 'No such check #' ]. ^c ]
In the above code, if a matching check number is found, the method will answer the object associated to it. If no prefix is found, Smalltalk will unwind the stack and print an error message including the message you gave and stack information.
CheckingAccount new: 31 "<0x33788>" error: No such check #
…blah blah…
CheckingAccount>>#error:
[] in Dictionary>>#at:ifAbsent:
Dictionary(HashedCollection)>>#findIndex:ifAbsent:
Dictionary>>#at:ifAbsent:
[] in CheckingAccount>>#check:
CheckingAccount>>#check:
UndefinedObject(Object)>>#executeStatements
Above we see the object that received the #error: message, the message
text itself, and the frames (innermost-first) running when the error was
captured by the system. In addition, the rest of the code in methods
like CheckingAccount>>#check:
was not executed.
So simple error reporting gives us most of the features we want:
However, there is a more powerful and complex error handling mechanism,
that is exception. They are like "exceptions" in other programming
languages, but are more powerful and do not always indicate error
conditions. Even though we use the term "signal" often with regard
to them, do not confuse them with the signals like SIGTERM
and
SIGINT
provided by some operating systems; they are a different
concept altogether.
Deciding to use exceptions instead of #error:
is a matter of
aesthetics, but you can use a simple rule: use exceptions only if you want
to provide callers with a way to recover sensibly from certain errors,
and then only for signalling those particular errors.
For example, if you are writing a word processor, you might provide the
user with a way to make regions of text read-only. Then, if the user
tries to edit the text, the objects that model the read-only text can
signal a ReadOnlyText
or other kind of exception, whereupon the
user interface code can stop the exception from unwinding and report
the error to the user.
When in doubt about whether exceptions would be useful, err on the side
of simplicity; use #error:
instead. It is much easier to convert an
#error: to an explicit exception than to do the opposite.
• Creating exceptions: | Starting to use the mechanism | |
• Raising exceptions: | What to do when exceptional events happen | |
• Handling exceptions: | The other side | |
• When an exception isn't handled: | Default actions | |
• Creating new exception classes: | Your own exceptions | |
• Hooking into the stack unwinding: | An alternative exception handling system | |
• Handler stack unwinding caveat: | Differences with other languages |
Next: Behind the scenes, Previous: Streams, Up: Tutorial