The Right Approach to Exceptions
H. S. Teoh
hsteoh at quickfur.ath.cx
Sun Feb 19 17:53:15 PST 2012
On Sun, Feb 19, 2012 at 11:58:19PM +0100, deadalnix wrote:
[...]
> I would add that, by thinking at your proposal of exception that may
> succed if you retry the same thing, phobos should propose a retry
> function that take as parameter a closure and and limit and will retry
> the operation until it succeed or that the limit is reached.
>
> The more I think of it, the more it make sense to have a property on
> Exceptions to explicit if a retry may help.
This is starting more and more to sound like what's described in the
link that bearophile posted elsewhere in this discussion:
http://www.gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html
I stand by my objection that if something might succeed if it can be
retried, then it needs to be retried in the called function, not the
caller.
I've already posted a summary of the above link, but I'd like to repeat
some of the salient points:
- With the current try/catch mechanism, we are limited to two modes of
recovery: (1) don't bother, just abort; (2) restart the operation from
scratch, and hope it won't fail this time.
- To have more intelligent error recovery requires that such recovery
take place *in the scope of the function that throws the exception*.
- However, the code that throws the exception is usually low-level, and
as such does not have the global, high-level context to decide which
course of action to take.
- By the time a thrown exception gets to said high-level code, the stack
is already unwound, the original execution context is long gone, and
the only recovery left is to restart the entire operation from
scratch.
Perhaps the "ideal exception handling facility" that Andrei is looking
for is a Lispian model, where:
- The low-level function that throws the exception also indicates a list
of possible recovery strategies;
- The high-level code that eventually calls the low-level function
registers exception recovery policies with the runtime (in the form of
delegates that choose between recovery strategies or prompts the
runtime to unwind the stack);
- When an exception is thrown, the runtime matches the thrown exception
with the recovery policy, and corrects the problem based on the
decision of said policy *in the execution context of the low-level
function where the problem occurred*. The stack is only unwound if no
recovery policy is available to correct the problem, or if the policy
says to abort the operation.
Note that the registration of recovery delegates needs to be out-of-band
(not passed as function parameters) because there can potentially be a
very long chain of calls before the low-level code is reached. Manually
propagating lists of recovery delegates through the entire call chain is
not practical. It also adds lots of noise to the code (clutters normal
code with exception-related code) and adds unnecessary CPU overhead for
the usual case when no problems happen.
That's why this needs to be done by the runtime system. You also want
language support for this mechanism, otherwise you end up with tons of
boilerplate code.
T
--
It only takes one twig to burn down a forest. It only takes one twit to
burn down a project.
More information about the Digitalmars-d
mailing list