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