3 ms·
In the code shown, `foo()?;` is equivalent to this: match foo() { Ok(val) => val, Err(err) => return Err(err.into()), }; (This isn’t exactly h
by chrismorgan 5y ago
In the code shown, `foo()?;` is equivalent to this:
match foo() {
Ok(val) => val,
Err(err) => return Err(err.into()),
};
(This isn’t exactly how it’s implemented—that detail is unstable and has actually changed <https://github.com/rust-lang/rfcs/pull/3058 https://github.com/rust-lang/rfcs/pull/3058> since ? was stabilised, without disrupting things!—but it’s equivalent in this instance. As examples of how it’s not exact: you can use ? on Option too; and inside a try block (unstable), ? isn’t a return, acting more like a break-with-value.)
For wrapping the error: note the .into() in the desugaring: it’ll perform any necessary type conversions which is the normal way you’d do error wrapping. But if you want to do anything more than that, or adding specific context, you’re still in luck! You can use method chaining to manipulate the result. In the standard library is map_err <https://doc.rust-lang.org/std/result/enum.Result.html#method.map_err https://doc.rust-lang.org/std/result/enum.Result.html#method...>:
foo().map_err(|err| f(err))?
And you can add other methods to such types with extension traits; as an example, the anyhow crate, popular for application-level error handling (where you don’t care about precise modelling of errors) makes it so that, on importing anyhow::Context <https://docs.rs/anyhow/1.0.44/anyhow/trait.Context.html https://docs.rs/anyhow/1.0.44/anyhow/trait.Context.html>, you can add context to an error like this:
foo().context("foo failed")?
foo().with_context(|| "foo failed")?