4 ms·
Rust 1.0 error story hasn't changed much? They added `expr?` as sugar for `try!(expr)`, but that's about it.
by fluffything 7y ago
Rust 1.0 error story hasn't changed much?
They added `expr?` as sugar for `try!(expr)`, but that's about it.
- majewsky 7y agoThe big problem is that there isn't a single error type that every function can return. Take this example: fn read_i32_from_file(path: &str) -> Result<i32, ???> { let bytes = std::fs::read(path)?; //may return std::io::Error let text = std::str::from_utf8(&bytes)?; //may return std::str::Utf8Error return text.parse(); //may return std::num::ParseIntError } What do you enter as error type in the type signature? In most cases, it would be sufficient to use Box<dyn Error>, but that requires boxing and thus an allocation, which is something that many libraries want to avoid to be useful for no_std or resource-constrained usecases. An answer to this could be to define enum ReadI32FromFileError { Read(std::io::Error), Decode(std::str::Utf8Error), Parse(std::num::ParseIntError), } and then you have to provide a bunch of trait implementations for that new error type (esp. to cast the constituent error types into this type). That's a whole lot of boilerplate, and most of the error handling crates are about cutting down on this boilerplate. Another problem with the std::error::Error trait is that until 1.30 it didn't provide a nice way to traverse error chains. Even now, the new cause() method may not be supported by all the error types from all the libraries you care about.
- richardwhiuk 7y ago`Box<dyn Error + Send + Sync>` is almost always fine
- ragnese 7y ago> What do you enter as error type in the type signature? In most cases, it would be sufficient to use Box<dyn Error>, but that requires boxing and thus an allocation, which is something that many libraries want to avoid to be useful for no_std or resource-constrained usecases. Okay, so you are in a resource-constrained environment. What would you do in C or C++? You can't do exceptions in C++ here, because there's allocation and other ugliness for embedded or whatever. You can always have your rust code return an int, like we do in C if the boilerplate is too much for you. On the other end, you have Kotlin and Swift Results. Kotlin type-erase the error completely. And I'm pretty sure Kotlin's Result allocates on failure. I'm not sure about Swift. But are you running Swift, with its heap allocated `class` and reference counting on embedded? You're surely not running Kotlin.
- majewsky 7y ago> You can always have your rust code return an int, like we do in C if the boilerplate is too much for you. Sure, if you have complete control over all the source code. I'd like to use my standard set of libraries regardless of whether the code in question is resource-constrained. (Side-note: I specifically said "resource-constrained" instead of "embedded" because you can have resource-constrained code in an otherwise not-constrained application, e.g. in tight computation loops where you want to avoid heap usage to benefit cache locality).
- roca 7y agoIt's true that the preferred idiomatic approach to implementing error types hasn't stabilized. However, that "churn" has all been in third-party crates, so > a lot of this churn could have happened "in userspace": different approaches to async or error handling would be library changes rather than language changes. is exactly what has been happening, for error handling.