2 ms·
I almost never see people "handle" errors and actually add value, though... it feels a lot like how people sprinkle timeouts throughout their logic that just se
by saurik 1y ago
I almost never see people "handle" errors and actually add value, though... it feels a lot like how people sprinkle timeouts throughout their logic that just serve to make the system less stable. Almost all of the time--like, seriously: almost all of the time, not 99% of the time, or 99.9% of the time, but almost every single time--you call a function, you shouldn't care what errors it can raise, as that's not your problem. In a scant handful of places throughout your entire project--in the context of a web site backend, this often won't even be in your code at all: it will be taken care of inside of the router--you will catch errors, report them, and provide a way for the operation to retry somehow; but, if you care why the error happened, either the API was designed wrong (which sometimes happens) or you are using it wrong. You have to already misunderstand this aspect of error design in order to even contemplate the existence of a language that forces people to deal with local error handling.
- Expurple 1y ago> almost all of the time, not 99% of the time, or 99.9% of the time, but almost every single time--you call a function, you shouldn't care what errors it can raise Sure, that's often the case. That's why dynamically-typed anyhow::Error is so popular. But I really care whether a function can raise at all. This affects the control flow in my program and composability of things like `.map()`. `Result` is so good because it makes "raising" functions just as composable as "normal" functions. When you `.map()`, you need to make a decision whether you want it to stop on the first error or keep going and return you Results with all individual errors. Rust makes it very easy and explicit, and allows to reuse the same `.map()` abstraction for both cases. > a language that forces people to deal with local error handling. It does that for the reason above: explicit control flow. See the "Can you guess why I used an intermediate variable" toggle in the article. It doesn't mean that you have to do full "local error handling" on every level. 99% of the time, `?` operator is used. Because, as you've said, 99% of the time you just want to propagate an error. That's understood in the Rust community and the language supports it well. When you need to wrap the error for some reason, `?` can even do that automatically for you. That's what makes anyhow::Error so seamless and sweet. It automatically wraps all concrete library errors and you no longer need to deal with their types. Basically, `Result<T, anyhow::Error>` is `throws Expection`. But, like, ergonomic, composable and actually useful.