It's worse than just exceptions in C++. There's (almost) no way for the caller of your function to catch it. It's a bit like this snippet:
std::optional<int> foo = <...>;
try {
return foo.value();
} catch(const std::bad_optional_access& e) {
std::cout << e.what() << std::endl;
abort();
}
It's the abort that is the crux of the issue here. Usually you would pass the std::optional up/down the call stack. If you don't control the types (e.g. using a library or a framework) you'd come up with some "default" value instead, like this:
std::optional<int> foo = <...>;
return foo.value_or(123);
Or in Rust:
let foo : Option<i32> = <...>;
return foo.unwrap_or(123);
But sometimes there's no good "default" value, and then you have to resort to just unwrap-ing the value, and accepting that the entire program will abort when that function call fails. Usually this is a sign of poor engineering somewhere, likely in a library you're using, and should be fixed; but sometimes you don't have the time to fix it, and then it ends up in production.
Rust does not have exceptions. You never have to try/catch. Functions usually encode the possible failures in their types, so you'd have something like this C++ snippet:
And then the caller of
downloadFilehas to decide what to do if it returns an error:However, Rust makes this whole thing a lot easier, by providing syntax sugar, and there are helper libraries that reduce the boilerplate. You usually end up with something like
(notice the
#[from], which forwards the error message etc from thestd::io::Errortype)The
Resulttype is kind of like astd::variantwith two template arguments, and, mostly by convention, the first one denotes the successful execution, while the second one is the error type.Resulthas a bunch of methods defined on it that help you with error handling.Consumer code is something like this:
Or
Which will just forward the error to your caller (but your function has to return
Resultas well), or proceed with the execution if the function succeeded.Finally,
download_file(url).unwrap()is if you can neither ignore, nor handle, nor pass the error to the caller. It will abort if the function fails in any way, and there's no (practical) way to catch that abort.