Comparing Exceptions and Errors

Steven Schveighoffer schveiguy at gmail.com
Wed Jun 8 01:14:28 UTC 2022


On 6/7/22 3:58 PM, frame wrote:
> On Tuesday, 7 June 2022 at 18:37:13 UTC, Steven Schveighoffer wrote:
> 
>>
>> My very common use of `scope(failure)` for my DB code:
>>
>> ```d
>> conn.exec("START TRANSACTION");
>> scope(success) conn.exec("COMMIT");
>> scope(failure) conn.exec("ROLLBACK");
>> ```
>>
>> This is hard to encapsulate into a type, as dtors only hook 
>> `scope(exit)` essentially.
>>
>> -Steve
> 
> That's fine as the Throwable is still thrown but since `scope(failure)` 
> acts as like catch-block, people may use it as replacement if there is 
> something more to do.
> 
> I personally like the clean, short syntax when I don't care about the 
> actual exception or if I know the called function has already handled 
> the exception and just rethrows it:
> 
> ```d
> bool fun() {
>       scope(failure) {
>           // do something
>           return false;
>       }
> 
>       badCode();
>       return true;
> }
> ```

Wait, what?

I'm looking at the spec and it says:

     A scope(exit) or scope(success) statement may not exit with a 
throw, goto, break, continue, or return; nor may it be entered with a goto.

Which specifically does not include scope(failure).

I would never have expected that to be a "feature"...

> 
> I know this is bad as I'm capturing a possible error here - but this is 
> what an unexperienced coder would do, because it works. The better 
> approach would be to use `scope(exception)`  (not typed, just as 
> keyword) that allows to act only on Exceptions so one cannot break 
> Exception vs Error paradigma and this also clarifies that usage of 
> `scope(failure)` is potentially dangerous if you return from it.
> 
> Anyway, I just put that here - maybe you mention it in your blog.

Ali's linked bug report suggests that it's happening for Errors too, 
which is going to cause major problems if something didn't get cleaned 
up properly.

I will update the blog post. My recommendation is going to be, don't 
circumvent the propagation of the throwable for now. Instead use a `try` 
+ `catch(Exception)`. I think we need a compiler change to not allow 
return if it's catching an Error.

There may be other "weird" cases that are not covered by the spec. Is it 
legal to goto a label inside scope(failure)?

Thanks for the heads up!

-Steve


More information about the Digitalmars-d-learn mailing list