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