“Say goodbye to try/catch blocks and hello to functional, composable error handling with the Result type”
I thought the same, but it’s not the whole story, and
@KentonVarda was (partially) right.
I was thinking that never-throw (sic) is the goal, and that everything should be wrapped in try/catch.
That’s not true. In any non-trivial code, some invariants have to be checked, and when they are violated, the only safe approach is to let the whole program fail with a plain error. It’s useless to wrap such an error in Result — result is for domain modeling only, and that’s what should be highlighted.
For example, my SQLite wrapper had a special SQLiteError. I realized, it was unnecessary, because, when SQLite fails, there is really nothing we can do except let it bubble to Sentry.
Kenton also wrote that Result is not necessary, if we use errors as values, and I understand that point of view, except when we want to leverage Result helpers, we need common API glue. Do we need such helpers? If we write idiomatic not fake pipe everywhere code, often we don’t.
So, if a code is misusing throw for business errors, then Result, or any other error-as-value abstraction, is recommended.
If a code throws an error that can not be meaningfully handled, then Result does not help.
To err is (not only for) human.