Towards a better conceptual model of exceptions (Was: Re: The Right Approach to Exceptions)

H. S. Teoh hsteoh at quickfur.ath.cx
Tue Feb 21 14:53:49 PST 2012


On Tue, Feb 21, 2012 at 07:15:29PM +0100, Artur Skawina wrote:
> On 02/21/12 17:56, H. S. Teoh wrote:
[...]
> I don't think something like this can reliably work - handling unknown
> error conditions in code not expecting them is not a good idea.

I'm not proposing we do this for *every* error. Only for those for which
it makes sense. And the code *does* have to expect what it's handling: a
particular category of problems, a category for which it makes sense to
handle recovery in a generic way. I'm *not* proposing this:

	try {...}
	catch(Exception e) {	// catch everything
		// generic code that magically handles everything
	}

If we could do that, this thread would've been over after 3 posts. :)


> After all, if the new error is of a similar nature as another one it
> could have been mapped to that one, or handled internally.

Which is what I'm trying to do with the categorization.

Internal handling, of course, can and should be done in those cases
where it's crystal clear how one should proceed. I'm addressing the case
where it can't be handled internally (else why would it throw an
exception / raise a condition in the first place?)


> Note that with my scheme the delegates can eg call another delegate
> provided in the exception from the lower level code - so things like
> that are possible. It's just that i don't think it's a good idea for
> low level code to use the exception mechanism to ask "Should I retry
> this operation?". The code either knows what to do (whether retrying
> makes sense) or could be provided with a predefined policy.

The delegate is the predefined policy. Except that it's much more
flexible than a global on/off setting. It has access to the registering
function's scope, based on which it can make decisions based on the
large-scale state of the program, which the low-level code doesn't (and
shouldn't) know about. Multiple delegates can be registered for the same
condition, and the most relevant one (the closest to the problem locus)
takes priority. Each delegate can implement its own policy on how to
deal with problems. The higher-level delegates only see problems that
the lower-level delegates decide to pass on.

In this way, lower-level delegates filter out stuff that they can handle
on their own, only deferring to the higher-level delegates when they
don't know how to proceed.  Your higher-level handler won't be handling
all sorts of trivial low-level problems, only the major issues that the
lower-level handlers can't already handle.


> If retrying occurs often during normal operation then throwing an
> exception every time is probably not the best way to handle this.

In fact, some experimental code that deadalnix & I are playing with
currently implements retry without try/catch, except when we need to
unwind the stack. So no performance hit there.


> And if it's a rare event - this kind of error handling adds too much
> overhead - programmer-wise, hence more bugs in the rarely executed
> parts of the program and probably java-style
> catch-everything-just-to-silence- -the-compiler situations, which are
> then never properly fixed...
[...]

We're currently playing with using templates to generate the boilerplate
stuff, so all you need to do is to write the template name and wrap a
block around the code to be retried. I think that's acceptable overhead
-- it's no worse than writing "try ... catch", and arguably far more
powerful.


T

-- 
Trying to define yourself is like trying to bite your own teeth. -- Alan Watts


More information about the Digitalmars-d mailing list