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

Artur Skawina art.08.09 at gmail.com
Tue Feb 21 10:15:29 PST 2012


On 02/21/12 17:56, H. S. Teoh wrote:
> On Tue, Feb 21, 2012 at 03:54:30PM +0100, Artur Skawina wrote:
>> On 02/21/12 09:15, H. S. Teoh wrote:
>>> The try-catch mechanism is not adequate to implement all the
>>> recovery actions described above. As I've said before when
>>> discussing what I
>>
>> Imagine that catch blocks are delegates. Now, when something throws an
>> exception, the catch handler is looked up, just like right now, except
>> the stack isn't unwound, the matching catch-delegate is called. If it
>> returns 'X' control flow is returned to the 'throw' scope, so that the
>> failed operation can be retried.  If it returns 'Y' then  the search
>> for another matching catch block continues, that one is called and so
>> on. If a delegate returns 'Z' the stack is unwound and control is
>> passed to the code following this catch statement.
> 
> It's not always as simple as "return control to throw scope", the point
> of not rolling back the stack is so that you can present a list of
> resolution alternatives to the catch block, and have it select one, then
> you proceed with that method of recovery.
> 
> These resolution alternatives need to be standardized, since otherwise
> you pollute high-level code with low-level knowledge (suboperation Y023
> 20 levels down the call stack has failure mode F04 which has recovery
> options R078, R099, R132, so I can catch F04, then choose between R089,
> R099, R132), making it only able to deal with a single problem decided
> beforehand by the coder. What you want is to be able to say things like,
> given any transient problem, I don't care what exactly, retry 5 times
> then give up. Or, given any component failure, I don't know nor care
> which component, try an alternative component if one exists, otherwise
> give up.
> 
> This way, if a new component is added to the low-level code, with brand
> new ways of failure, the high-level code can still handle the new
> failures, even though when it was written such problems didn't even
> exist yet.

I don't think something like this can reliably work - handling unknown
error conditions in code not expecting them is not a good idea. 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. 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. If retrying occurs often during normal operation then
throwing an exception every time is probably not the best way to handle
this. 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...

artur


More information about the Digitalmars-d mailing list