Hacker News new | ask | show | jobs
by embedding-shape 226 days ago
I usually divide things in "errors" (which are really "invariant violations") and "exceptions". "exceptions", as the name implies, are exceptional, few and when they happen, they're usually my fault, "errors" on the other hand, depending on the user, happens a lot and usually surfaced to the user.
1 comments

why not divide things into errors and bugs (programming errors)?
That's subtly different. It's secondary whose fault is this, what primarily matters is whether you should continue with the rest of the process.

There is always a cleanup layer, the trick is to choose well between 1 and 2:

  1. Some code in the same OS process is able to bring data back to order.

  2. OS can kill the process and thus kill any corruption that was in its address space.

  3. Hardware on/off button can kill the entire RAM content and thus kill any corruption that spilled over it.
Take for example an unexpected divide by zero, that's a classic invariant violation. The entire process should blow up right there because:

- it knows that the data in memory is currently corrupted,

- it has no code to gently handle the corruption,

- and it knows the worst scenario that can happen: some "graceful stop", etc., routine might decide to save the corrupted data to disk/database/third-party. Unrecoverable panic (uncatchable exception) is a very good generic idea, because persistently-corrupted-data bug is a hundred times worse than any died-with-ugly-message bug as far as users are concerned.

> Take for example an unexpected divide by zero, that's a classic invariant violation. The entire process should blow up right there because:

> - it knows that the data in memory is currently corrupted,

> - it has no code to gently handle the corruption,

are these conditions or implications?

- corruption isn't necessary: it could be the consequence of a bug

- corruption can be handled sometimes: fetch the data from the source again, apply data correction algorithms

- you know and control what the graceful stop does; maybe not save the corrupted data to disk? or maybe save it to disk and ask the user to send it to you

I took several assumptions to build an argument why some errors should result in process-level termination.

By "corruption" I mean much more than merely a hardware bit error. I mean any situation when data no longer has a meaning for a user.

By "unexpected" I mean that the program has not been prepared to deal with the situation: there is no code there to "fetch the data from the source again", etc.

> you know and control what the graceful stop does

No, in fact I'm exploring here situations when I don't know this with certainty.

Both bugs and exceptions can be reasonably thought of as programmer error, but they are not the same kind of programmer error. Exceptions are flaws in the code — conditions that could have been caught at compile time with a sufficiently advanced language/compiler. Whereas bugs are conditions that are programatically sound, but violate human expectations.
A little nuance: bugs are not just conditions that are programmatically sound. They can encompass exceptions.

If a bug triggers an exception then with a strong compiler that is sufficiently advanced then these bugs can be found by the compiler.

Bugs require execution so a compiler cannot find bugs.

Exceptions also require execution, but that does not suggest that they are encompassed by bugs. The lack of a third term tells that there is no overlap. If "bug" covered both exceptions and where human expectations are violated, there would necessarily be another term just for the case where human expectations are violated. But there is no such term...

...that I've ever heard. If it is that I've been living under a rock, do tell.

No you haven’t been living under a rock your definitions are just off and you didn’t read carefully what I wrote. Or you’re just overly pedantic.

I wrote bugs can cover exceptions. Think hard about what that sentence means in English. If I can do something it means I can both do something and not do something. So that means there are exceptions that are bugs and exceptions that are not bugs.

The reason why it’s important to illustrate this difference is because a large, large number of exceptions occur as a bug.

> So that means there are exceptions that are bugs

Which, like before, is false. Are you, perhaps, confusing exceptions (the concept; what we're talking about here) with the data structure of the same name? A bug could erroneously lead to the creation of an exception (data structure), but that wouldn't be an exception (concept), that'd just be a bug.

There is no situation where an exception (concept) is also a bug, unless you take "bug" to mean something akin to general "programmer error", where exceptions are subset thereof. But, as before, we know that's not how "bug" is used as there is no other terminology for human expectation violations to fill the void. No need as that is already what "bug" refers to.

> a large, large number of exceptions occur as a bug.

That doesn't really make any sense. Maybe if, again, you have confused exceptions (concept) with exceptions (data structure), then it could start to mean something, but even then "large, large" is one hell of a claim. Let's be real: The vast majority of exceptions (data structure) are created by programmers who mistakenly believe that "exception" is another word for "error". While not exactly a good idea, that use falls under neither exceptions (concept) nor bugs. In second place, exceptions (data structure) are created due to exceptions (concept). I'm sure exceptions (data structure) being created due to bugs has happened before, but I've never seen it.

I'm currently working on something that requires a GPU with CUDA at runtime. If something went wrong while initializing the GPU, then that'd be an exceptuion/bug/"programming error" most likely. If the user somehow ended up sending data to the GPU that isn't compatible/couldn't be converted or whatever, then that'd be an user error, they could probably fix that themselves.

But then for example if there is no GPU at all on the system, it's neither a "programming error" nor something the user could really do something about, but it is exceptional, and requires us to stop and not continue.

> If something went wrong while initializing the GPU, then that'd be an exceptuion/bug/"programming error" most likely.

That depends if it is due to the programmer making a mistake in the code or an environmental condition (e.g. failing hardware). The former is exceptional if detected, a bug if not detected (i.e. the program errantly carries on as if nothing happened, much the dismay of the user), while the latter is a regular error.

> But then for example if there is no GPU at all on the system, it's neither a "programming error" nor something the user could really do something about, but it is exceptional

Not having a GPU isn't exceptional in any sense of the word. It is very much an expected condition. Normally the programmer will probe the system to detect if there is one and if there isn't, fall back to some other option (e.g. CPU processing or, at very least, gracefully exiting with feedback on how to resolve).

The programmer failing to do that is exceptional, though. Exceptions are "runtime compiler errors". A theoretical compiler could detect that you forgot to check for the presence of a GPU before your program is ever run.

The grey area is malfunctioning CPU/memory. That isn't programmer error, but we also don't have a good way to think about it as a regular error either. This is what "bug" was originally intended to refer to, but that usage moved on long ago and there is seemingly no replacement.

That’s interesting. I’d actually consider this a user error because it’s only in the user’s power to fix it.

For example:

1. You’d want to display a message that they need a GPU.

2. Call stack information isn’t helpful in diagnosing the issue.

Not all exceptional circumstances are bugs