4 ms·
as someone who works 95% of the time in rust, how to handle my errors is never a problem for me. I think the issue is the expectations of people coming into it
by jstrong 6y ago
as someone who works 95% of the time in rust, how to handle my errors is never a problem for me. I think the issue is the expectations of people coming into it with a different frame of reference, expecting the kind of traceback/exception framework built in - and for that to be a typical debugging workflow.
like 95 times out of 100, I just `.map_err(|e| /* code to convert e to return type's error... */)` and I'm done. the other 5 times I create a local error enum to represent the different types of error that can be returned.
most importantly, the overwhelming gladness I have that code somewhere deep in my stack can't throw an exception vastly outweighs the "pain" of the ongoing incremental work it takes to handle errors intelligently throughout my code.
- rklaehn 6y agoRust error handling is great for reliable systems. But it used to be really annoying when just doing exploratory coding. With the anyhow crate, this problem is solved as well. Just use anyhow if you just want to try something out quickly without being slowed down by error type mismatches, and then later refine it to a handcrafted error type. I prefer rust error handling over all other languages I worked with (scala, java, C++, C, javascript, typescript, ...).
- egnehots 6y agofor exploratory coding you can also just unwrap, assert, panic.. It's useful to remember that error handling is optional in those cases :)
- unrealhoang 6y agoanyhow with ? is even shorter than unwrap. If it’s likely to have error at some point, I’d throw in a .context, it is so convenient. Edit: typo.
- edflsafoiewq 6y ago? requires the return type be annotated with an error type and the success case be annotated with Ok, for all functions up the stack, between the current function and where handling occurs. unwrap is purely local.
- rklaehn 6y agoI somehow still prefer ?, even in places where unwrap would be perfectly fine, like tests. unwrap is somehow unpleasant to look at. E.g. you can have tests that return an anyhow::Result<()>, and use ? anywhere in the test. The test will fail if the result is not Ok(()). Sure, you have the additional boilerplate of the return type annotation and the final Ok(()), but the test logic itself reads nicer, I think.
- simias 6y agoCompletely agree. I used to create my own error type(s) manually and implement the various conversions for 3rd party crates and it was quite a lot of boilerplate but with anyhow (for applications where you don't really care about strict error types) and thiserror (when you need to be a little more thorough). Actually that's effectively TFA's solution, if they had used thiserror/anyhow from the start there might not have been an issue to begin with. Admittedly it took me a while to find these crates since they're not part of std. Maybe the community should come together to create a curated list of third party crates that should probably be known by all Rust devs? Crates like thiserror, anyhow, rand, serde, clap and other "de-facto standard" crates?
- wronghorse 6y agoThis is really interesting because I recently found the anyhow crate and I was wondering why it's not mentioned anywhere else. Definitely feels like useful information that a newly minted Rust dev could make use of.
- simias 6y agoIndeed. I wish I learned about it earlier myself, it would've saved me some boilerplate in the past.
- nwellnhof 6y ago> Rust error handling is great for reliable systems. Last time I checked, Rust couldn't even catch malloc failures.
- wizzwizz4 6y agoTo be fair, these days malloc doesn't fail; your program crashes when it tries to use the memory, and there's nothing you can do about it. (But I agree that this is a problem with Rust's alloc system.)
- folmar 6y agoIt can, it just doesn't when the 0physical memory is exhausted, but there are other conditions $ ulimit -v 10240 < printf("%p\n", malloc(1024*1024*128)); > nil
- pedrocr 6y agoRust also has the traceback/exception error handling mode in the panic cases. And since there's no standard way to check those at compile time you're left to fuzz the code to find all the possibilities (or use some hacks). It would be great if the compiler could be put into a mode where panics are handled like errors that need to be explicitly handled. Maybe something like: 1) At the function level or crate level being able to specify if the code can or can't panic, sort of like safe/unsafe function signatures. 2) Being able to have blocks of code return MaybePaniced<T> and have to turn that into an error or other result. If it's not handled and the function/crate is marked as nopanic the compiler rejects the code. It would make the code more robust, and allow for an ecosystem where just like nostd you can specify that your crate is nopanic which helps in some environments.
- johnsoft 6y agoI found a crate that claims to do #1: https://github.com/dtolnay/no-panic https://github.com/dtolnay/no-panic This also looks interesting: https://github.com/Technolution/rustig https://github.com/Technolution/rustig
- pedrocr 6y agoYep, the no-panic crate is the hack I mentioned. It's using the linking process to fail compilation if I remember correctly. It only works on individual functions. rustig I didn't know and looks very interesting, thanks. Having it integrated in the compiler as annotations and guarantees would be ideal.
- safarimonkey 6y agoHere is one (recently created) that operates on the whole program rather than a single function: https://crates.io/crates/no-panics-whatsoever https://crates.io/crates/no-panics-whatsoever