Rust is great, however the safety aspect gets in the way sometimes
The right granularity for error handling is important, as well as making it easy to handle (abort? providing a default value? doing something else?)
It's not that it is not important, but code usability is important as well, lest it goes on the way of C++ hell (though I don't think it can get that bad, there are some warts - like "methods" and traits)
> The right granularity for error handling is important, as well as making it easy to handle (abort? providing a default value? doing something else?)
Option<T> and Result<T,E> achieve just about the best level of granularity I could imagine for error handling.
Suppose you're trying to fetch a value from a map (use case for Option<T>), or read some value over some fallible I/O stream (use case for Result<T,E>).
Want to abort if the value is missing or an error occurred?
Just call unwrap() and ready yourself for (completely safe!) crash reports. unwrap() is just a way to dynamically assert certain invariants.
Want a default value in those cases? Just call or() or or_else() on the Option<T> or Result<T,E> value you have.
Want to do something else? Use Rust's pattern matching features and branch depending on whether the value was obtained, on conditionals relating to the value (or error), and more!
I can see Option and Result irking people who don't want to embrace a more functional (programming) mindset. They can be kind of a pain to deal with procedurally without the and_then, or_else, map and such. The new '?' construction will definitely help with this.
The appeal of exceptions, to me, has always been that they allow you to largely separate your error handling from your procedural logic since the catch block can usually go at the end of the method/function and can usually be written later. This means you can write and test code and then come back and handle error conditions after you've gotten the success path working. Option/Result force you to at least acknowledge the possibility of an error at the point when you're writing your logic. Whether that's ?/try!, .unwrap(), a match or writing in a more functional manner, error handling can't literally be an afterthought the way it is with unchecked exceptions.
I'm not arguing that this is a bad thing, and it may be a push in the right direction for many programmers. But it's still a push and many don't enjoy being pushed.
At least I'm not the only one disappointed in Rust's error handling strategy. I still firmly believe that exceptions are the best error handling strategy we've concocted so far and that Rust (and Go) represent a big step backwards in language design in this respect. It's still hard to get over Rust's default abort-on-OOM behavior that arises from the awkwardness that would arise from surfacing the possibility of allocation failure from every part of stdlib.
> the catch block
"The" catch block? For each function? Some people misunderstand exceptions and think that every function needs a catch block that cleans up resources allocated in that function. I hope you're not one of these people.
Idiomatic exceptional code has very few catch blocks. That's part of the appeal.
My criticism might be due to a bit of impedance mismatch, that's for sure
(Or maybe I'm just missing exceptions - because, as an example: I want to read a file and what I care about is getting a fd, anything before that "doesn't matter" and I don't want to care about every step)
The right granularity for error handling is important, as well as making it easy to handle (abort? providing a default value? doing something else?)
It's not that it is not important, but code usability is important as well, lest it goes on the way of C++ hell (though I don't think it can get that bad, there are some warts - like "methods" and traits)