Comparing Exceptions and Errors

Steven Schveighoffer schveiguy at gmail.com
Sat Jun 4 16:55:31 UTC 2022


On 6/4/22 7:57 AM, kdevel wrote:
> On Friday, 3 June 2022 at 23:40:50 UTC, Steven Schveighoffer wrote:
>> During the last beerconf, I wrote a short blog post about how `Error` 
>> and `Exception` are different, and why you should never continue after 
>> catching `Error`s.
>>
>> Feedback welcome, I didn't announce here when I wrote it because it's 
>> kind of small/insignificant, but maybe it can help newcomers to the 
>> language: 
>> https://www.schveiguy.com/blog/2022/05/comparing-exceptions-and-errors-in-d/ 
>>
>>
> 
> Here my feedback:
> 
> 1. What if div is called with x = -2147483648 and y = -1? Isn't code
>     which allows a divisor == 0 to propagate to the CPU an error? Must
>     the code thus not throw an object instantiated from a subclass of 
> `Error`?

Well, that is just a toy example to show code that might use an Error. 
It's not intended to be a fully-fleshed-out function. I recommend simply 
using the divide operator in real code.

The point of an `Error` is that your code can assume it cannot happen. 
If it does happen, the code is invalid. This is reflected in the fact 
that the compiler will omit cleanup code if an `Error` is thrown (it can 
assume that it will never happen). The point of using `Error` is for a 
last resort check for program correctness (because you failed to 
validate the input before getting to that point).

> 
>     What if I have that function div used in code which is called from say
>     controller code of a CGI binary. Or likewise from a vibe.d-thread 
> servicing
>     a web request? How do I isolate that fault? Do I have to spawn a 
> subprocess
>     as Walter suggested in the case of memory corruption [1]?
> 
>     [This is of course all rhetorical!]

vibe should exit the process if an `Error` is thrown. There is a version 
you can specify to have it catch `Error`, but it would only be for 
debugging. https://vibed.org/docs#compile-time-configuration (see 
`VibeDebugCatchAll`)

One thing that always bugs me in my vibe code is out of bounds errors 
for arrays. I actually replaced some arrays with an `Exception` throwing 
wrapper because I didn't want to crash the whole server for certain 
cases, and I didn't want to continuously validate array indexes.

> 
> 2. Since 2017 or so I have written some 10 KLOC of D, maybe about two dozen
>     classes deriving from Exception. But I did not annotate any of my 
> methods or
>     function with "nothrow" nor did I author any class deriving from 
> `Error`.
> 
>     What does that mean? Am I `Error` blind?

As long as you aren't catching `Throwable` or `Error`, you should be 
fine. Simply not marking things `nothrow` doesn't mean that they won't 
be inferred `nothrow`. `auto` and template functions are inferred.

In practice, there are probably very very few places where this can bite 
you. Which also means, if it does bite, it's going to be really really 
hard to track down.

> 
> 3. Can you provide some piece of code which *must* throw `Error` and cannot
>     throw an appropriate Exception?

As Paul said, this is up to your API. If you specify that you assume the 
inputs to the function are cleansed, then you can correctly throw an 
Error if they are out of spec.

A great example are range functions. Often times you see at the 
beginning of any `popFront` method the statement `assert(!empty);`. This 
is universally accepted, as you shouldn't be calling `popFront` if you 
haven't checked for `empty`.

-Steve


More information about the Digitalmars-d-learn mailing list