In a world without exceptions...
So far, everything I've read about exception handling (EH) has been negative. The language implementor perspective is that they add a burden for design, implementation, and optimization. On the user side, it's every bit as easy to write bad code with the facility as without it.
Here's a quick rundown of the three major ways to implement EH:
- Require the runtime code to set up and tear down exception response thunks on the stack as part of normal execution. This is slow in the normal case of no exception.
- Allow the runtime to install event handlers for problems, like "on error goto" in BASIC, or the *nix signals system. This can constrain the language's flexibility as a platform.
- Use a table to relate instruction addresses with corresponding handler thunks. This is fairly fast, but it restricts a number of useful compiler optimizations.
- Catch everything, do nothing: This is mainly found in Java, where you have to declare checked exceptions unless you catch them.
- Catch nothing, let the runtime die: This is far preferable to the above, but not helpful in a long-running server process.
- Be oblivious to the possibility of an exception in certain modules: This can leave program structures in an inconsistent state if an exception blows right through code that looks correct.
When a fault happens, the knowledge of response policy is often separated from the code that notionally relied on not having the fault. In C++, Java, Python, Ruby, and indeed the vast majority of popular Algol-family languages with EH, the exception policy is always "terminate and roll back stack frames until exception is handled." Some call this a poor policy choice. For example, if a memory allocation fails, the right thing is probably to collect garbage and try again, but that's a decision that only the heap knows how to make. Thus, throwing OutOfMemoryException is probably not what you want. The programmer may also know some more ways to free space. Why lose all the program state it that becomes necessary?
Some languages provide ways to try to repair a fault and continue or retry the failed operation. The appearance is that these complicate everything. Implementation means dealing with yet more cases. More importantly, the programmer now needs to know symbolic names for arcane causes of failure or else deal with programs that die untimely deaths due to unhandled faults.
I would like to propose an alternative mechanism that doesn't rely on the idea of exceptions as we know them.
There are only a few major kinds of faults that a computer program can have.
- Syntax errors are caught by the compiler.
- External faults require policy, usually to retry the operation after making repairs.
- Logical errors (such as zero division, popping an empty stack) tend to invalidate any assumption of correctness of all associated code, which is when you want stack traces and diagnostics sent somewhere intelligent.
- Solving the wrong problem is something that the computer cannot help you with.
Basically, the only mechanism needed for all of this is a per-thread callback for unhandled errors (with complete stack trace), and pervasive application of a design principle that subsystems should be told in advance what to do about problems. In something like Perl, that would be like passing around subroutine references.
The "per-thread" thing is subject to some interpretation. Consider a servlet engine. If your database dies, then what should happen? What should users see in their browsers? How should we respond to a SQL error?
I took on a Java Servlet project some years back that had lots of problems. Mainly, things were mysteriously not working. My ultimate solution was to rip out 99.99% of the exception mishandling code and replace it all with a system-wide response to failure: show a stack trace to the end user on a dark green (unusual) background. Several important things happened.
- My client was initially shocked about the apparent new bugs.
- He calmed down once he understood what was going on.
- He knew full well when something didn't work, at the earliest possible juncture.
- I soon found out what to fix, in the client's priority order, in e-mail.
- I didn't have to dive in server logs. Ever.
- Whoever maintains the code from now on will always have ideal bug reports.

0 Comments:
Post a Comment
Subscribe to Post Comments [Atom]
<< Home