Comment by bestouff
5 years ago
Rust shines when doing error handling. No way to ignore errors, but properly handling them often adds just a single question mark to your code. Everything stays readable and lightweight.
Of course the error handling story is still perfectible but so far it's already one of the best I know.
The trouble I’ve had as a beginner is crafting error types for those “Union of multiple existing error types”. E.g., myfunc() can return an IO error or a Parse error. The boilerplate for creating a new error type (absent macros) is significant, and while I’m aware that there are macro crates available which automate this, it’s not clear to me which of these if any are “most standard” or otherwise how to distinguish between them.
There are many ways to do it, like you said. Over time, the most popular options have shifted as new support from the standard library arrived. How you handle the errors can boil down to whether or not you really care about what kind of error it is, or just if an error occurred.
Two popular crates for handing these situations are thiserror [1] and anyhow [2], for handling errors by type and handling all errors, respectively.
There are additional ways, like just returning a Box wrapper around the stdlib error type [3], or just unwrapping everything. It depends on what your program needs.
[1] https://crates.io/crates/thiserror
[2] https://crates.io/crates/anyhow
[3] https://play.rust-lang.org/?version=stable&mode=debug&editio...
As a beginner to Rust, this blog post has been excellent, and it has really helped me understand the idiomatic way to handle errors.
https://blog.burntsushi.net/rust-error-handling/
You can "ignore" error is Rust using _ like in Go.
Not really. In Go you can `val, _ := func()` and use the value even if there is an error. AFAIK there is no equivalent in Rust (for Option) outside of unsafe shenaniganry. You can choose to panic / return err / etc, but you can't choose to use the value regardless of the presence of an error.
Yep. I'm pretty sure that even with unsafe shenanigans, you can't access the value without being very explicit about it. You'd need something like:
At this point, the fact that you've skipped an error check should be abundantly clear to anyone reading your code.
You can return tuples from Rust fns just like you would in Go, if that's your thing - no unsafe necessary:
Or more typically, you might use one of the many fn s such as unwrap_or, unwrap_or_else, unwrap_or_default, etc. - to provide your own appropriate default value. I usually find that useful default values are often caller specific anyways (and doesn't require remembering which fns return which default values on error):
Alternatively you can use out parameters, which occasionally crops up in Rust's own stdlib:
Also, the "error" type might contain values itself, although you're certainly not ignoring the error if you use it:
1 reply →
If you're not going to use the success value, you can ignore errors in Rust easily:
This does not even give a warning.
1 reply →
That's still very explicit. If you don't bind the returned Result to something (`let _ = ...`), the compiler bitches at you.
Go lets you ignore errors by just not binding them at all.