Scoped Error in Rust
29 points by hongminhee
29 points by hongminhee
color-eyre together with tracing can do this. the context that you attach to functions (instead of callers) is... spans. a nice side effect of this is that your logs (=events) will have the same context.
requiring to put the code into a closure likely doesn't play well with async
pub fn expect_error<T, E>(
msg: impl Into<Cow<'static, str>>,
body: impl FnOnce() -> Result<T, Frame>,
) -> Result<T, E>
where
E: From<(Cow<'static, str>, Frame)>,
{
body().map_err(|context| (msg.into(), context).into())
}
I like this. I'm already writing my own bad error library so vendoring this one instead seems like a good idea.
This seems wrong:
pub struct Frame {
/// The underlying error that caused this context.
pub source: Box<dyn StdError + Send + Sync + 'static>,
I would not be able to match on the error type since its a Box<dyn StdError>, it should be generic with the error type.
exn for example stores the error with the type and impl Deref's it https://github.com/fast/exn/blob/main/exn/src/impls.rs#L128-L140
Good article nonetheless, I do wish there was a winning crate in the anyhow style, I do wish exceptions do actually become a thing in Rust, because quite often you just want to throw at a point and propagate it all the way upwards. For example a DatabaseError in a HTTP application will propagate all the way to the request handler and print 500 and that shouldn't have cost in either code verbosity or normal execution if it is "rare". ("cost of zero-cost exceptions" blog articles can shed more light on this)
It is great that the standard library does not throw exceptions and makes you write safe code for libraries, but its not so convenient for applications, and if there were an API to "convert a error into an exception and raise it with a trace that can optionally be caught", it would be really nice. I do not know how this can interoperate with existing code though, specifically objects created or borrowed in the intermediate calls.