3 ms·
I once read some advice that totally changed the way I think about exceptions: "The ratio of try/finally to try/catch in your programs should be about 10:1." T
by apenwarr 14y ago
I once read some advice that totally changed the way I think about exceptions: "The ratio of try/finally to try/catch in your programs should be about 10:1." That is, if you're doing a lot of specialized try/catch, you're doing it wrong. (And in C++ you generally use RAII instead of try/finally, but same idea.)
When you do it this way, exceptions make your code cleaner, not uglier, and more readable, not less.
To relate this to the OP, the proposal here implies a naive idea of what it takes to "recover" from an exception. It's very rare to be able to recover at the low level, and even if you can do it, it's hard to be 100% sure you got it right. Low-level code includes details that you're trying to hide from the caller; if the caller has to be able to fix the details, you've ruined your abstraction. If an inner library has a failure, it's kind of unlikely that the caller knows how to recover from that specific detailed failure so you can pick up where you left off. What you actually want is to just let the caller know there was a problem and then retry the whole big operation.
And hence the 10:1 ratio. Lots of try/finally blocks all the way into the deep inner library, and one try/catch block near the top: when your mainloop catches a critical problem, see if it can recover. Mostly this will be by fixing something (possibly asking the user to correct some input, or waiting a bit in case the network server had a problem) and then retrying the whole thing by just calling the function over again.
Someone in another comment suggested that an example of the "recover" technique is when a kernel fixes up an exception (say a page fault) and then resumes the user process. I disagree; in my opinion, you should think of userspace calling the kernel, not the other way around. Even accessing memory is a kernel call (albeit usually a highly optimized one). A page fault is not really an "exception", it's just a slow-path memory access. You wouldn't expect it to change your program flow, so it tries hard not to. It's perfectly okay for an "inner" function (kernel) to recover itself so as not to disturb the abstraction for the "outer" layers (userspace). It would be much weirder for the outer layers to try to fix things up for the inner layers; that abstraction goes the wrong way.