Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I tried Rust for the first time a few months ago. One of the things that really impressed me was that it was very easy to just get started. Even though the language is very different than I'm used to, I was able to "just jump in" without jumping through a lot of hoops. I was working with 3rd party crates very quickly.

One thing that I think does need improvement is the error handling. Far too many idiomatic examples just panic for error handling. There's no good way to just group errors by a higher-level classification and fall through to a generic error handler. As a result, the choice is between panic on error, or very detailed and verbose error handling. There's no middle ground.



> There's no middle ground.

Not at all. This is what the ? operator is for (was try! before).

The idiomatic rust way is to have your own Error type that implements From for other Error types that you may encounter (io::Error, Utf8Error, etc.).

Then you can simply just write let result = dosomething()?; for any operation that may fail. If an error happens, function will return with the error.

I don't think you can do it any cleaner, given the constraints Rust is operating under.


The From is The Right Thing, but it can be hard to convince people used to unchecked exceptions and costless casting of this. (I say costless, you pay for it every time you don't cast...)


For error handling, I'd encourage you to look at error-chain. It makes it pretty simple to propagate all your errors with try!/? so long as all your functions return a Result. And the quick_main macro can handle the panicking if you let it propagate all the way to main. Hopefully once the ? In main RFC gets released, quick_main won't even be necessary.

There's a couple of annoyances to it. The documentation is really sparse for something as integral as it aims to be. And there's a frustratingly large number of third-party crates that don't use standard error types and prevent you from calling chain_error to convert from their error types to yours.

But once you get the gist of it, a few lines of boilerplate gives you the ability to handle errors concisely and correctly throughout your program.


There actually is a way to do that, which is to return Results, with error types that implement From so the nested errors can be "wrapped" in the generic ones, and then you can just use the ? postfix operator as an alternative to unwrapping in order to bubble up the errors.

If you're designing your own errors then there's some boilerplate you need to allow for the error wrapping, though you can always take the cheap way out and use Box<Error> as your error type (as any error can be wrapped in that).

And there's an RFC that's been accepted (https://github.com/rust-lang/rfcs/blob/master/text/1937-ques...) to allow main to return a Result, so you can use the ? operator in main, which will let you avoid even more unwraps, especially in example code.


There's certainly middle ground. I spent some time explaining it my CSV tutorial: https://docs.rs/csv/1.0.0-beta.4/csv/tutorial/index.html#bas...


There's a whole chapter in the second edition of the book devoted to error handling https://doc.rust-lang.org/book/second-edition/ch09-00-error-...


Yes, that chapter painfully explains my point.

Most of the replies pointed out the new ? operator, which I'll have to check out. (One of the things that I like about the Rust community is that they constantly improve.)

The thing is, if you've only handled errors via return codes in C, then Rust's system is a major improvement. The challenge comes once you've programmed with exceptions that have inheritance. It's pretty easy to set filters higher up in the stack and "not care" lower in the stack. This allows you to effectively ignore error handling for functions that only fail in obscure corner cases, because a filter higher up in the stack can handle so many different errors. (Operations that require cleanup can also be written in a way that cleanup code always runs, as some languages support try-finally.)

That's probably the hardest thing for me to adjust to in Rust. Lifetimes take care of the try-finally part, but I still can't figure out how to have generic error filters higher in my stack.


At the point you want to handle them, you use match instead of ?, and then handle the cases you care about.


Existing error handling facilities in Rust may not suit every use-case. For me personally, the difficulty with the `?` operator (and try! macro) is that the File + Line info about the source of error is lost. Also, I want something simpler than the approach taken by the `error-chain` crate. My current solution is to use some custom macros to check for errors and display an execution trace (example here: https://play.rust-lang.org/?gist=a7fb903ce2bbb37914ab380d342... )


Does rust have __FILE__ etc.? Special constants?



I was thinking the same as you until I learned about Result<(), Box<Error>>. It’s super quick and not really that far off from the detailed hand-roll solution.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: