Comparing Exceptions and Errors
Steven Schveighoffer
schveiguy at gmail.com
Sun Jun 5 20:53:32 UTC 2022
On 6/5/22 8:45 AM, kdevel wrote:
> On Sunday, 5 June 2022 at 01:43:06 UTC, Steven Schveighoffer wrote:
>
> [...]
>
>> But you aren't perfect, and so maybe you make a mistake, and trigger
>> an Error. The compiler handles this unexpected condition by unwinding
>> the stack back to the main function, printing the error and exiting,
>> so you can go fix whatever mistake you made.
>
> For this purpose nobody needs a separate subclass named `Error`. That
> works with `Exception`s.
You can use Exceptions instead. But the difference is they are part of
the program instead of considered a check on the program itself.
There's a need for both.
>
> [...]
>
>>> If the code threw an `Exception` instead of an `Error` everything
>>> would be fine.
>>
>> I think the point of Errors is that you can remove them for efficiency.
>
> elephant/room.
Why? If you have a correct program, you shouldn't ever have errors
thrown. If you do have errors thrown that's something you need to
address ASAP.
>
>> In other words, just like asserts or bounds checks, they are not
>> expected to be part of the normal working program.
>
> "removing [Errors, asserts, bounds checks] is a bit like wearing a
> life-jacket to practice in the harbour, but then leaving the
> life-jackets behind when your ship leaves for open ocean" [1]
It's more like leaving the floaties behind when you are doing a swim meet.
>
> [...]
>> Consider the normal flow of a range in a foreach loop, it's:
>>
>> ```d
>> // foreach(elem; range)
>> for(auto r = range; !r.empty; r.popFront) {
>> auto elem = r.front;
>> }
>> ```
>>
>> If both `popFront` and `front` also always call `empty` you are
>> calling `empty` 3 times per loop, with an identical value for the 2nd
>> and 3rd calls.
>
> Solution: Implement explicitly unchecked popFront() and front() versions.
That's terrible. Now I have to instrument my code whenever I have a
weird unknown error, changing all range functions to use the
`checkedPopFront` and `checkedFront`, just to find the error. Instead of
letting the asserts do their job.
>
>> Having the assert allows diagnosing invalid programs without crashing
>> your program,
>
> That depends on the understanding of "crashing a program". If library
> code throws an `Error` instead of an `Exception` I have to isolate that
> code in a subprocess in order to make my program gracefully handle the
> error condition.
You don't gracefully handle the error condition. It's like saying
gracefully handling running into the guardrail on a road. You just
crash, and hope you don't die. You don't just graze into it and keep
going thinking "well, the guardrail did it's job, glad it's there, I
plan on using it every time I go around that corner."
>
> Think of CGI processes which provide output direct to a customer. If
> there is an assert the customer will see the famous Internal Server
> Error message (in case of apache httpd).
An assert triggering means, your code did something invalid. It should
crash/exit.
Now we can have *totally separate* debates on what should be an Error
and what should be an Exception. And not to belittle your point, I
understand that there can be a philosophy that you *only* want
recoverable throwables for certain code domains (I myself also have that
feeling for e.g. out of bounds errors). It's just not what D picked as
an error handling scheme. We have both recoverable exceptions, and non
recoverable errors.
-Steve
More information about the Digitalmars-d-learn
mailing list