eyre-rs / eyre

A trait object based error handling type for easy idiomatic error handling and reporting in Rust applications
Apache License 2.0
1.41k stars 68 forks source link

Integration with the `tracing` crate #58

Open loyd opened 3 years ago

loyd commented 3 years ago

First of all, thanks for the great crate. I've been waiting for a similar library for a long time. I highly like the idea of having a custom handler, because it allows more tight integration with an environment.

I'm writing the actor system and want, among other things, to provide a good experience with error handling:

eyre allows this by providing custom handlers.

However, now I am stuck in integration with the tracing crate (elfo's logging system is based on it now). My goal is to print something like

... something wrong    error="aa"   error.source="bb"  error.location="path/to/file:42"  error.stacktrace=[..]

for calls like

error!(error = &some_eyre_error as &dyn Error, "something wrong");

The problem is that Report doesn't implement Error. I understand that it's impossible now, so I just want to hear an opinion on how it can be solved. Maybe I miss some easy solution.

Maybe, eyre should provide some wrapper that implements Error and have a method to expose internally stored Report? Of course, it can be provided by elfo, but it complicates using libraries that depend only on eyre and tracing.

Related:

yaahc commented 3 years ago

There are potentially paths to getting Report to impl Error. We're setting up an experiment crate for the error handling project group and one of it's modules is experimenting with a way to make an equivalent of Box<dyn Error> that can still implement the Error trait. https://github.com/yaahc/trial-and-error/blob/main/src/boxerror_replacement.rs. This solution would essentially be equivalent to the suggestion at the end of your message about having an Error and a method to access it as a Report.

Alternatively, I haven't checked in on it recently but my understanding is that tracing has been evolving their Value API. It may be better to add a cfg enabled tracing::Value impl for Report that then bridges the gap, though that may also require some changes to the EyreHandler trait to let the customized handlers also provide context back through the Value API.

Either way though I'm not sure what the best way forward will be, and I don't have any great answers short term. You can extract the dyn Error from a Report but that will lose all additional context stored in the handler. I don't know of a good way to also output this info, but I'm open to suggestions.