[HN Gopher] The Two Kinds of Error
___________________________________________________________________
The Two Kinds of Error
Author : zdw
Score : 25 points
Date : 2026-03-01 23:29 UTC (1 days ago)
(HTM) web link (evanhahn.com)
(TXT) w3m dump (evanhahn.com)
| noelwelsh wrote:
| I agree with this, and I'd add there are two modes of processing
| errors: fail-fast (stop on first error) and fail-last (do as much
| processing as possible, collecting all errors). The later is what
| you want to do when, for example, validating a form: validate
| every field and return all the errors to the user.
| lexx wrote:
| Nice article. I agree with the differentiation. You could also
| classify them as errors that should be fixed and errors that
| should exist. Some would argue that validation errors are not
| really errors on a system level. They are only errors on the user
| level. On the system level they are a feature
| metalliqaz wrote:
| This post seems to conflate using `throw`, `raise`, etc. with
| crashing. The idea that 'handling' an error does not involve
| `throw`/`catch`, `try`/`except` is very strange to me. The
| exception facility is often the most elegant way to check inputs,
| and if I remember correctly the Python documentation says as much
| as well.
| taylorallred wrote:
| It makes me think that it's worth sitting down and considering
| what all the valid outcomes for a piece of functionality are. A
| user typing in a string in the wrong format is not necessarily
| "exceptional", whereas running out of memory while getting the
| input would be. I feel like programmers too often treat perfectly
| valid outcomes to be errors. For example, in Rust I'll see
| Option<Vec<Foo>> and I ask myself if we could just use the empty
| vector as a valid return value.
| taylorallred wrote:
| Another interesting article on error handling:
| https://www.dgtlgrove.com/p/the-easiest-way-to-handle-errors
| supermdguy wrote:
| I'd also add errors with third-party systems, which aren't the
| developer's or the user's fault, but which are probably worth
| handling nicely (e.g. retry with backoff).
| joshdick wrote:
| This is 4XX versus 5XX errors in HTTP.
| mjw1007 wrote:
| It's common that if you extract a function or a module with a
| well defined interface, that function or module can't tell
| whether a "bad" input indicates an expected or an unexpected
| error.
|
| For example division by zero often indicates an "unexpected"
| error, but it wouldn't if you were implementing a spreadsheet.
|
| So to me the approach of using different forms of error reporting
| for the two kinds of error doesn't seem promising: if you imagine
| you had to implement division yourself, which kind of error
| should it report? Should you have two variants of every fallible
| function so the caller can choose?
| tl2do wrote:
| The expected/unexpected distinction assumes you have the capacity
| to anticipate failures in the first place. But that capacity
| varies - even among experienced developers, everyone has blind
| spots shaped by their specific history. What's "obviously
| expected" to one senior dev is a surprise to another. The
| article's model is useful, but there's a prerequisite it doesn't
| address: the ability to expect is itself unevenly distributed.
| thelittlenag wrote:
| I don't really like this article. There isn't anything
| particularly noteworthy to noticing that some computations have
| outcomes that allow some form of recovery, and other outcomes do
| not.
|
| But there are some obvious follow up questions that I do think
| need better answers:
|
| Why is recovery made so hard in so many languages?
|
| Error recovery really feels like an afterthought. Sometimes
| that's acceptable, what with "scripting" languages, but the poor
| ergonomics and design of recovery systems is just a baffling
| omission. We deserve better options for this type of control
| flow.
|
| Also, why do so many languages make it so hard to enumerate the
| possible outcomes of a computation?
|
| Java tried to ensure every method would have in its signature how
| it could either succeed or fail. That went so poorly we simply
| put everything under RuntimeException and gave up. Yet resilient
| production grade software still needs to know how things can
| fail, and which failures indicate a recoverable situation vs a
| process crash+restart.
|
| Languages seem to want to treat all failures as categorically
| similar, yet they clearly are not. Recovery/retry, logging, and
| accumulation all appear in the code paths production code needs
| to express when errors occur.
|
| Following programming language development the only major
| advancements I've noticed myself have been the push to put more
| of the outcomes into the values of a computation and then further
| use a type system to constrain those values. That has helped with
| the enumeration aspect, leaving exceptions to mainly just crash a
| system.
|
| The other advancement has been in Algebraic Effects. I feel like
| this is the first real advancement I've observed. Yet this
| feature is decried as too academic and/or complex. Yes, error
| handling is complex and writing crappy software is easy.
|
| Maybe AI will help us get past the crabs at the bottom of the
| bucket called error handling.
| IshKebab wrote:
| This sounds very neat in theory, but in practice errors are a
| continuum between these two extremes and there isn't really a
| clean dividing line.
| smitty1e wrote:
| I was expecting Type I & II from statistical theory:
|
| "Type I error, or a false positive, is the incorrect rejection of
| a true null hypothesis in statistical hypothesis testing. A type
| II error, or a false negative, is the incorrect failure to reject
| a false null hypothesis"
|
| https://en.wikipedia.org/wiki/Type_I_and_type_II_errors
___________________________________________________________________
(page generated 2026-03-03 23:00 UTC)