[HN Gopher] You Can't Handle Errors
___________________________________________________________________
You Can't Handle Errors
Author : sirwhinesalot
Score : 61 points
Date : 2024-02-14 07:52 UTC (3 days ago)
(HTM) web link (btmc.substack.com)
(TXT) w3m dump (btmc.substack.com)
| loeg wrote:
| (Because the author redefines error to tautologically mean an
| unhandled condition.)
| sirwhinesalot wrote:
| Not my definition, the IEEE Standard Glossary of Software
| Engineering Terminology definition. Yes the title is clickbait
| (I mention that's intentional in the post) because people keep
| mixing up faults and failures, be it i.e. Elm's approach (all
| in on faults) vs Erlang's approach (all in on failures).
|
| Without properly defined terminology understanding the
| difference in focus leads to unproductive discussion.
|
| EDIT: In your defense the later standards appear to have made
| "error" a uselessly wishy-washy term again, so eh. The terms
| fault/error/failure as defined in the post are still used in
| the study of fault tolerance.
| Groxx wrote:
| The fact that a standard exists somewhere for something
| doesn't mean that it's an accepted-in-practice usage. Or even
| _vaguely imply_.
|
| You probably don't have a jar of SRM 2387 peanut butter on
| your shelf, for instance.
|
| The three-term separation makes plenty of sense and when I
| see all three together in a doc it's generally clear that
| they mean something along those lines, but it's far from
| normal use.
|
| ---
|
| Late edit: to make this perhaps a bit more useful /
| constructive: because of ^ this, it's being perceived as a
| clickbait title. And perception is all that matters in "is
| this title clickbait", because it's what determines the level
| of interaction someone is willing to pay at the beginning.
|
| Clickbait-title leads to clickbait-pushback. You don't have
| to change it of course, and it fits with the post's
| narrative, but I can pretty much guarantee that it'll keep
| causing this kind of reaction in some (many? few? idk)
| people.
| sirwhinesalot wrote:
| Fair enough, I was taught the terminology in university on
| a course on fault tolerance.
|
| Personally I wish their usage was more standardized, in
| fact if it was I wouldn't have had to explicitly mention
| they're taken from IEEE 610.12-1990 and that I'm using them
| to split "error" into 3 separate but related ideas for
| clarity.
|
| Either I made it clear in the post I didn't make up the
| terms so no idea what the original commenter is on about.
| Groxx wrote:
| Yeah, it's not a totally unknown standard or anything.
| But I feel pretty safe claiming that "bug" (unobserved in
| code) / "error" (handled in code) /
| "crash/fatal/unhandled error" (obvious) is both far more
| common _and_ far clearer at a glance... which is probably
| why it 's more common.
|
| In technical documents, the standard can be useful for
| being very explicit and unambiguously identifiable. I'm
| far from convinced that it deserves use elsewhere tho.
| sirwhinesalot wrote:
| I'm replying to you Groxx but hopefully panzi will also
| see it. I definitely see where both of you are coming
| from. The issue (I feel) is that if I were to do as you
| suggest, and just use 3 commonly used but not agreed upon
| terms (bug, error, crash), then the original comment of
| this thread would be justified in their criticism (that
| I'm making up my own definitions for clickbait).
|
| I actually had to present my own definitions for terms in
| my article about OOP, so I could explain why I like
| objects but not OOP, because the terminology in practice
| is so diluted to be next to useless :(
| edderly wrote:
| If it helps I think you're right to take this approach.
|
| In my experience defining error as 'handled' or
| handleable in code can often not be particularly helpful.
| Are the values from errno(3) always considered as
| handled?
|
| EINVAL is almost always in "your" terms a fault, ENOSPC
| or EPIPE likely could only be handled as complete
| failures.
|
| What I see too often is code which which propagates
| Groxx wrote:
| I might push for a different set of divisions there tbh.
|
| errno(3) is _handle-able_ because the information exists
| and it is possible to use. It 's the same as any other "a
| problem occured" signaling mechanism in that sense. Its
| main sin is being out-of-band of the trigger, so it's
| extremely easy to forget.
|
| Whether it _is handled_ (checked) in code is a
| subdivision of handle-able. Some signaling mechanisms are
| better about preventing not-handled than others,
| depending on context.
|
| Whether you can _recover from it_ (do something else, try
| again until success, etc) is also a subdivision of
| handle-able, and is completely unrelated to whether it
| was handled or not. And I think I can claim that in
| literally all cases the "recover-ability" is also
| completely unrelated to the _kind_ of problem (ENOSPC vs
| EINVAL) - it only depends on what you are trying to do
| right now, which depends on the rest of the program and
| the user intent. If it was _inherently_ unrecoverable, it
| wouldn 't be errno(3), it'd just never return (e.g. kill
| your process, infinite loop, etc).
|
| Under that framework, ENOSPC is just a normal handle-able
| error. It's _frequently_ a fatal failure that is easy to
| forget, but it 's easy to come up with something that
| expects and recovers from it, e.g. a lossy caching tool.
| Similarly, EINVAL is an unrecoverable error if you are a
| tool that fails on bad input, like a compiler, despite
| being easily recoverable in some cases (probing for
| feature support and gracefully degrading, perhaps).
| panzi wrote:
| I too learned that terminology at university almost 20
| years ago. Haven't heard it used like that since. Yes,
| precise language would be useful for communication, but
| in this case it feels like a lost cause. Nobody uses
| these terms like that.
| nordsieck wrote:
| > Nobody uses these terms like that.
|
| Yeah - it feels a bit like "Mebibyte". Sure, it's
| technically the correct name of a base-2 Megabyte. But
| people just use "Megabyte" and use context to figure out
| if people mean base-10 or base-2.
| f1shy wrote:
| The problem is that people writing norms are (typically)
| people without any contact with reality. In theory they
| are great. No place in practice. Best example iso stack
| vs. Tcp/ip
| kiitos wrote:
| Mebibyte is well defined. Error is not.
| Nevermark wrote:
| But as pointed out, "Megabyte" is not clearly defined in
| informal usage.
|
| Informally, it has two specific meanings, and a third
| useful fuzzy meaning when the distinction between 10^6
| and 2^20 does not matter.
| kiitos wrote:
| If you try to assert a specific definition of a specific
| term like "HTTP error 503" then you have some authority.
| But if you try to assert a specific definition of a
| generic term like "error" then you don't really have the
| same authority, and you can't be surprised when other
| systems don't follow your definitions.
| f1shy wrote:
| I hate engineers playing lawyer, and also I do not know the
| IEEE definition, but acording to ISO26262 your definition is
| wrong: fault is undetected, error detected (but may or maynot
| be handled by for example resundancy) and an unhandled error
| that results in deviation of req. sys. behaviour is a
| failure.
|
| Also note: fault can be a bug in SW, but an unexpected
| behaviour of the HW
| sirwhinesalot wrote:
| It's not playing lawyer, it's agreeing upon some
| terminology for the purpose of discussion. I was accused of
| making up terms, I didn't, I used existing terms from one
| particular standard. The very reason I used existing terms
| from a standard was to avoid the very accusation I got
| anyway in this hackernews thread, but that's the internet
| for you.
|
| I even mention in the article that the term fault is used
| differently in the context of hardware faults, different
| standards have different meanings for the same terms, which
| is why I also lay them out and don't expect you to know the
| standard in the article.
| nyrikki wrote:
| Efforts like the "IEEE Standard Glossary of Software
| Engineering Terminology", where from an era that we learned
| what didn't work, which linguistics had learned way before
| CS.
|
| The IEEE didn't go 'wishy-washy' they accepted that at that
| scope, 'Descriptive' was the appropriate approach and
| 'Prescriptive' was inappropriate for a broad context.
|
| Same thing happen with most English dictionaries.
|
| https://www.merriam-webster.com/grammar/descriptive-vs-
| presc...
|
| "Ubiquitous Language" concepts from DDD is probably the best
| example here.
|
| Domain specific language is always polysemous to a wider
| scope. So DDD typically defaults to allowing domain experts
| (think accountants, not accounting software developers) to
| object to a rigorous "Ubiquitous Language" for interfacing
| with each other. This is important because when domain
| experts object to a formal definition as proposed, they are
| possibly concerned about nuances in that language that are
| important.
|
| Obviously they may just be pedantic, but the default
| assumption is that they are trying to convey something
| important about the domain of discourse.
|
| The Prescriptive model of enterprise architecture utterly
| failed to live up to it's promise, in part because word sense
| ambiguity is a pervasive characteristic of natural language
| even at the scope of an enterprise.
| sirwhinesalot wrote:
| Fair comments, I wasn't hoping to use the IEEE standard as
| an appeal to authority, just clarifying I didn't make up
| the terms.
|
| Sadly as you say, these formal definitions don't end up
| agreed upon, which is why it is always important to clarify
| what you mean when you use a certain word (which I
| hopefully did in the post).
| Dwedit wrote:
| I hate sites that make things pop up when you select text.
| sirwhinesalot wrote:
| Apologies for that, it's a substack thing... I used to have a
| self hosted website but wasted more time tweaking the theme
| than writing :(
| ktpsns wrote:
| What a great text with useful references and links. Cudos to the
| author, who is also the OP.
| sirwhinesalot wrote:
| Do let me know if I got anything wrong or missed something.
| worksonmine wrote:
| A graceful message instead of letting the entire process crash is
| a way of handling even unexpected errors, i.e. 5XX on the web.
| Without anticipating them some backends will completely crash.
| ATMLOTTOBEER wrote:
| I agree with everything in this article. Can we work together lol
| sirwhinesalot wrote:
| If you're asking I'm guessing your current work colleagues
| don't keep these distinctions in mind. Neither do mine x).
| They're great folk though!
| nwhnwh wrote:
| Do you write for yourself or for other people?
| sirwhinesalot wrote:
| They're pure brain dumps on whatever is on my mind at the time.
| But if other people find my incoherent rambling useful, then
| it's worth sharing on the interwebs. Hope you got something out
| of it!
| nwhnwh wrote:
| I realize that it may be a rude question or too direct, but I
| thought it could cut the conversation down into something
| quicker. That's all. You can write whatever you want of
| course... but the modern world put a crazy highway in our
| brains, my friend. Give me the info like you would give a
| soldier an order. I would fall in love with you for it.
| sirwhinesalot wrote:
| All of my close friends who read the post had the same
| complaint, no offense taken. It's hard to keep my ADD
| addled brain creatively entertained and write a coherent,
| straight-to-the-point kind of post at the same time.
|
| More time in the oven (editing) is something I need to
| invest in.
| nwhnwh wrote:
| :hot-beverage:
| wredue wrote:
| FWIW, the creators of rust themselves distance themselves from
| "if it compiles, it works", because this is obviously not true.
|
| If your definition of "works" ignores behavioural requirements,
| then I suppose.
| catears wrote:
| I liked the article so I wanted to give you some feedback. Hope
| it is useful to you!
|
| - I don't think the definitions of error and failure are 100%
| correct as stated. Looking at the IEEE definition that you
| reference, I interpret error meaning the difference between the
| value that is stored in the program, and the correct/intended
| value. For example if we expect to have a value of 100, but in
| fact have 110, the error is 10. I don't think that whether the
| value is observed or not is what categorizes it as either an
| error or a failure. If I run my program in the debugger and find
| that a value is off from what it is supposed to be, does that
| shift it from an error to a failure?
|
| - One point I think you should have leaned more into is how
| language constructs and tools can help prevent failures, or cause
| more of them if they are bad. You bring up the point with Haskell
| and Rust, and how they systematically reduce the number of faults
| a programmer can make. You also bring up the point of Exceptions
| introducing a lot of complexity. I think these two examples are
| great individually. I think putting them together and comparing
| them would have been powerful. Maybe a section that argues why
| Rust omitting exceptions makes it a better language. - A side
| note since I also hate exceptions: did you know that the most
| common (and accepted?) way to communicate exceptions in C# is via
| doc comments written manually by humans. Good luck statically
| analyzing that!
|
| - A lot of the text revolves around the terms error, failure, and
| fault and how people use these in communication. Often with
| different ideas of what the words mean. Even the titles
| (jokingly? "correctingly"?) reference this. Even with the
| definition at the start, the ambiguity of these terms was not
| dispelled. I think a major part of that was the text using the
| terms like you defined them, and also the common "misunderstood"
| versions of the terms. I think a strategy you could have deployed
| here is to use less overloaded words throughout the article and
| sticking to those throughout the article. For example (without
| saying these are the best terms for the job), instead of fault,
| error, and failure, using defect, deviation, and detected
| problem.
|
| - A note on the writing style. Many words are quoted, and many
| sentences use parenthesis to further explain something. At least
| to me, these things make the text a bit jumpy when overused. I
| would try to rewrite sentences that end with a parenthesis by
| asking myself "what is missing in the sentence so I don't need to
| resort to parenthesis?". Don't be afraid to break a long sentence
| into many!
|
| Hope my comments come of as sincere, if not then that's on me!
| Good luck with your continued writing.
| sirwhinesalot wrote:
| Constructive feedback is always appreciated!
|
| The only thing I'll comment on is the IEEE stuff. I was taught
| these terms in a university course on fault tolerance. You'll
| find slides from various courses using them like this or
| similar if you search on Google, and that particular IEEE
| standard was mentioned as the source (I never personally read
| it). I have read a later standard that rather than defining
| error specifically, mentions all the various ways in which the
| term is used.
|
| The thing is, the actual standard is irrelevant, it wasn't
| meant as an appeal to authority. Rather, it's a source of 3
| related terms (fault/error/failure) that can be used to refer
| to the 3 distinct ideas discussed throughout the post.
|
| Your suggestions for alternative names are just as valuable and
| just as useless, neither the ones in the standard nor your own
| are generally agreed upon. My hope was that by using a somewhat
| common triple I would have avoided pointless discussion on the
| terms themselves, rather than the ideas discussed in the post.
|
| As this hackernews comment section demonstrates, I was all for
| naught ;)
| layer8 wrote:
| > A side note since I also hate exceptions: did you know that
| the most common (and accepted?) way to communicate exceptions
| in C# is via doc comments written manually by humans. Good luck
| statically analyzing that!
|
| Java having checked exceptions is the primary reason I'm
| sticking with that language. Many libraries don't use them,
| unfortunately, but an application that embraces them
| systematically is bliss in terms of error handling, because at
| any place in the code you always know exactly what can fail for
| what non-bug reasons.
| sirwhinesalot wrote:
| They had the right idea but implemented it poorly (overly
| verbose to work with, as is much of java). The end result
| were people taking too many shortcuts.
| marcosdumay wrote:
| > did you know that the most common (and accepted?) way to
| communicate exceptions in C# is via doc comments written
| manually by humans.
|
| Well, the accepted way to communicate them in Python is "we
| don't". I think C++ follows that same principle, but the
| ecosystem is extremely disconnected, so YMMV.
|
| Java tried to do a new and very good thing by forcing the
| documentation of the exceptions. But since generics sucked for
| the first ~20 years of the language, and nobody still decided
| to apply them to the exceptions, it got bad results that
| discouraged anybody else from trying.
| sirwhinesalot wrote:
| I think for dynamic languages exceptions are just a fact of
| life and it doesn't really make much sense to worry about
| them, you can't rely on the type system to remind the
| programmer of all the cases they need to handle.
|
| So thinking in terms of failure handling is the way to go.
| lucas_membrane wrote:
| >> Errors are almost always the result of faults. Barring cosmic
| rays, hardware issues or really unusual race conditions between
| the application and the operating system, if an error occurs it
| is because the programmer screwed up and introduced a bug. <<
|
| The 'cosmic ray' category has taken in an awful lot of territory
| since computers started running multiple programs at once and
| sharing resources between programs and with the world in general.
| About 60 years ago, perhaps lightheartedly, it was suggested that
| computer instruction sets should contain a branch-on-chipbox-full
| instruction. The chipbox, a shared resource, was where the
| cardpunch disposed of the confetti produced by punching cards. As
| we were learning that anything that could go wrong would, it was
| logically inferred that if a full chipbox was ignored long enough
| while punching cards, the computer would find a way to stop or
| fail, and no software could prevent that possibility on its own.
| A comparable situation in this century is that typical computers
| today allow the operator to 'adjust' the system clock, but a very
| small fraction of software is written to accommodate all the
| possible consequences of non-monotonic time, time being a shared
| resource. And if you do write software to handle said
| consequences, how do you handle it if the program has no way of
| telling if it is running on a system on which non-monotonic time
| is allowed or not-allowed?
| sirwhinesalot wrote:
| I always love seeing these historical anecdotes on hackernews
| and I couldn't be happier to see one on my own post. Thank you!
| k3vinw wrote:
| This is why I like the Either monad found in functional
| programming. You either have your return value or the error. No
| exception handling nonsense.
| rowls66 wrote:
| Is it really that much different? You still need to handle a
| Left value, and a lot like handling an exception.
| Const-me wrote:
| > error, which is an unobserved, incorrect internal state
|
| For example, amount of available space on the system drive is not
| an internal state. However, once the number reaches zero,
| failures of all software are very likely to happen. The software
| will fail regardless of static type systems or unit tests
| coverage.
|
| In my experience, external things like that (not enough disk
| space, not enough memory, unsupported instructions, broken TCP
| connections) cause large percentage of failures in the software
| I'm developing.
| bubuche87 wrote:
| Some thoughts. 1/ I think that it's not always possible to modify
| the domain. For example, I could have a function that takes a
| name of a file as parameter and returns a CanBeWritten object.
| Now, I could have a function that open a file in write mode and
| take an object of this type as parameter.
|
| The issue is that between the moment I acquire this object and
| the moment I use it, the file could, you in fact, become non-
| writeable. (There was a post on hn about this idea of using the
| type system like this
| https://news.ycombinator.com/item?id=35053118 ).
|
| I think you focus a lot on software issues and neglect the
| hardware ones. But it's a choice.
|
| Still my thoughts (but at this point you already understood that
| it was going to be like that the entire post): I think that when
| a fault is detected (when it becomes a failure if I follow your
| definitions), an attempt to fix the problem and return to a
| normal state can actually fail - by incorrectly fixing the issue.
| Like: you have three times the same integer (redundancy) and one
| of them have a bit flipped. You decide that the one different
| from the two other is the incorrect one. You detected a problem,
| you tried to fix it. But it could be the case that two bitflips
| occured at the same position.
|
| There is no definitive solution to that, but documenting all the
| detected problems AND the fixes applied to them would help.
|
| And for the error messages ... Well, my position is that most of
| the time they are useless for the end user. They can be useful
| for the developer. For the end user, the best error message (if
| such a message is required) is something unique enough to be
| copy-pasteable on Google to find a solution that the user will
| not understand but will be able to apply.
|
| I used to consider (when I started computer science) that an
| algorithm is like going from point A to point B on a city map.
| There is essentially one "good" path and a huge quantity of
| "wrong" paths were you can get lost. And by trying to find your
| way, you can make the situation even worse.
___________________________________________________________________
(page generated 2024-02-17 23:01 UTC)