C++ brought exceptions to mainstream programming; Java goes further with checked exceptions. But are exceptions the one way to report all errors? Scala and Go suggest there is more than one kind of error, so there should be more than one kind of error reporting, and different responses to errors. I’ll show the Scala and Go approaches to the error problem, and how to apply this to Python.
Exceptions were designed for “exceptional conditions,” when you simply don’t know what to do within your current context. C++ steered us toward using exceptions for error reporting and Java institutionalized it. And yet, sometimes it seems akin to pulling a fire alarm when the floor gets dirty, the sink clogs or the dog has an accident.
What should we do instead? Certainly, some conditions justify exceptions, but numerous others are expected errors; Forcing the caller to use try and except right at the call site seems overkill. C showed us that returning special values never worked out very well -- we could never settle on the values and the resulting interface didn’t make it clear enough to the caller that they must respond to error conditions.
The standard error-reporting practice in the Go language is to return a tuple holding success and null-or-failure objects, while in Scala you return a disjoint union that can be either a success object or a failure object. Both cases require the programmer to analyze the result; you can no longer just assume the result is valid. This produces the same effect as checked exceptions (that is, you can’t ignore the fact that the expression might fail) but without the visual noise and distraction of exception handling.
I'll show some of the history and past experiments in error handling, then based on the Scala and Go approaches, I’ll show how you can modify your Python coding style to produce more robust error handling.