The Right Approach to Exceptions

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Sun Feb 19 19:17:23 PST 2012


On 2/19/12 9:06 PM, H. S. Teoh wrote:
> On Sun, Feb 19, 2012 at 08:34:30PM -0600, Andrei Alexandrescu wrote:
>> On 2/19/12 7:58 PM, H. S. Teoh wrote:
>>> On Sun, Feb 19, 2012 at 05:38:23PM -0600, Andrei Alexandrescu wrote:
> [...]
>>>> No dependence on context. The bit simply tells you "operation has
>>>> failed, but due to a transitory matter". That is information local
>>>> to the thrower.
>>> [...]
>>>
>>> But *which* transitory matter? A temporary outage on the network? A
>>> timeout due to excessive CPU load? A full disk (which is transitory
>>> because some other process might remove a large file in the interim)?
>>
>> Doesn't matter.
>>
>>> Without knowing the context, this information is of little use.
>>
>> It is. User code may decide to retry the high-level operation (of
>> which the low-level failure has no knowledge).
> [...]
>
> But on what basis will it make this decision? All it knows is that
> something went wrong somewhere deep in the call stack, and it's
> presented with a binary choice: retry or abort.

No. The information is: "There's been failure, but due to a transitory 
cause." In a high-level transaction, it doesn't matter which particular 
step failed. If whatever failure was transitory, the transaction can be 
attempted again.

> It doesn't know what
> that problem was.

Doesn't have to.

> So how would it know if retrying would help? Saying
> that it "might" help doesn't seem useful to me.

Retrying helps because the error happened because of a temporary cause. 
That info is known at the raise place, and nicely passed up to the 
high-level command.

> It's only useful if you present this choice to the *user* along with the
> error message encapsulated in the exception, and let the user make the
> decision on the basis of the error message.

That's up to the application. A server application, for example, can't 
ask the user. We log and we have configurable number of retries.

> I think we're all agreed that parsing the error message is not a viable
> solution, so basically the catch block is presented with a blind binary
> choice of which it knows nothing about.  Such a choice is meaningless to
> a computer program.
>
> Do you have a concrete scenario in mind where such a decision would
> actually be useful? Otherwise we'll just end up with boilerplate code
> copy-n-pasted everywhere of the form:
>
> 	auto retries = SomeArbitraryNumber;
> 	do {
> 		try {
> 			...
> 		} catch(Exception e) {
> 			if (e.is_transient&&  retries-->  0)
> 				continue;
> 			throw e;
> 		}
> 	} while(false);
>
> But since this block is completely independent of what's inside the try
> block, why not just put it where the exception is generated in the first
> place?

I explained this. The raise locus does not have access to the high-level 
context.


Andrei


More information about the Digitalmars-d mailing list