Ever
since the beginning of programming languages, error handling has been one of
the most difficult issues. Because it’s so hard to design a good
error-handling scheme, many languages simply ignore the issue, passing the
problem on to library designers who come up with halfway measures that can work
in many situations but can easily be circumvented, generally by just ignoring
them. A major problem with most error-handling schemes is that they rely on
programmer vigilance in following an agreed-upon convention that is not
enforced by the language. If the programmer is not vigilant, which often occurs
when they are in a hurry, these schemes can easily be forgotten.
Exception
handling
wires error handling directly into the programming language and sometimes even
the operating system. An exception is an object that is “thrown”
from the site of the error and can be “caught” by an appropriate
exception
handler
designed to handle that particular type of error. It’s as if exception
handling is a different, parallel path of execution that can be taken when
things go wrong. And because it uses a separate execution path, it
doesn’t need to interfere with your normally-executing code. This makes
that code simpler to write since you aren’t constantly forced to check
for errors. In addition, a thrown exception is unlike an error value
that’s returned from a function or a flag that’s set by a function
in order to indicate an error condition – these can be ignored. An
exception cannot be ignored so it’s guaranteed to be dealt with at some
point. Finally, exceptions provide a way to reliably recover from a bad
situation. Instead of just exiting the program, you are often able to set
things right and restore the execution of a program, which produces much more
robust systems.
It’s
worth noting that exception handling isn’t an object-oriented feature,
although in object-oriented languages the exception is normally represented
with an object. Exception handling existed before object-oriented languages.