Chapter 13. Error Handling
The two central difficulties of programming are the same as the two central difficulties of road safety: like cars, programs are built by humans; and, like cars, programs are driven by humans.
Debugging (see Chapter 18) is the art of overcoming the fallibility of those who create software systems. Error handling is the art of surviving the fallibility of those who drive such systems.
Effective and maintainable error handling is one of the keys to creating software that can be considered robust. Even a program with no internal bugs[*] must still interact with the environment in which it executes: at very least, the operating system, filesystem, terminal I/O, hardware devices, and network connections.
That environment must be treated as hostile, because any or all of its components may fail in some unpredictable manner. Robust software must allow for that possibility, detect when it occurs, and either overcome the problem, if possible, or report it and fail gracefully. All of which comes under the mantle of error handling.
This chapter suggests several coding practices that can help. Those practices are all based on two fundamental principles. The first is that all detectable run-time errors must be detected, classified, and reported. The second is that it should not be possible to ignore any detected error without a conscious and visible effort.
The importantthough perhaps not obviousconsequence of these two principles is that detectable errors must be allowed to propagate only upwards (to callers), not laterally (to other statements within the same scope), and certainly never downwards (into subsequent subroutine calls).