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.35k stars 63 forks source link

feat: implement serialize for report #168

Open thewh1teagle opened 4 months ago

thewh1teagle commented 4 months ago

I use eyre with tauri. When returning a result from it, it requires that the error implements Serialize (as it returns it to the browser). So instead, I had to return std::result::Result<(), String> (which of course implements it) and map many errors to a string each time:

#[command]
fn hello() -> Result<(), String> {
  do_something().map_err(|e| e.to_string())?;
}

With this feature, I can now return an eyre result and propagate almost any error.

#[command]
fn hello() -> Result<()> {
  do_something()?;
}
thewh1teagle commented 4 months ago

Turns out that by default err.to_string() in eyre returns from fmt::Display, and it doesn't include the backtrace in the error string, and the final error string (which returns to the browser in tauri) is useless.

I'm thinking of a way to include the backtrace conditionally in the serializer from eyre, What do you think about adding serialize_backtrace feature which will be used as:

use serde::{ser::Serializer, Serialize};
use crate::Report;

impl Serialize for Report {
    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        if cfg!(feature = "serialize_backtrace") {
            serializer.serialize_str(format!("{:?}", self).as_ref()) // include backtrace
        } else {
            serializer.serialize_str(self.to_string().as_ref())
        }
    }
}
thewh1teagle commented 4 months ago

Sounds even better. I'm not sure how it can work with a custom handler (or how Eyre currently works with custom handlers).

Anyway, I think that should be another feature, and the default serializer should be just like the default error, with a backtrace (currently, the format in the PR doesn't include a stack trace).

ten3roberts commented 3 months ago

Clippy is failing on master due to introducing additional lints in a new version, I'll fix it up, so don't worry about it.

jsimonrichard commented 3 months ago

This is great! I'm working on another tauri project, so this would be helpful.

Since color_eyre re-exports eyre, could you add serialize as a feature to that as well?

MordechaiHadad commented 2 months ago

Whats the status of this? would really appreciate this.

LeoniePhiline commented 2 months ago

Whats the status of this? would really appreciate this.

There seems to be no consensus on the structural serialization format.

Serializing the Debug representation is easily done by crate users by implementing Serialize on a newtype wrapper.

The real interesting serialization would include information internal to eyre::Report, such as the error chain (backtrace) and stack trace for each error in the chain - where available.

It seems to be that this needs some more design work before we can settle on an implementation.

The serialization output would be part of the public API. Thus, if we serialize a Debug representation of the eyre::Report, we are bound to sticking with that.

ten3roberts commented 2 months ago

Whats the status of this? would really appreciate this.

There seems to be no consensus on the structural serialization format.

Serializing the Debug representation is easily done by crate users by implementing Serialize on a newtype wrapper.

The real interesting serialization would include information internal to eyre::Report, such as the error chain (backtrace) and stack trace for each error in the chain - where available.

It seems to be that this needs some more design work before we can settle on an implementation.

The serialization output would be part of the public API. Thus, if we serialize a Debug representation of the eyre::Report, we are bound to sticking with that.

Exactly.

I think best approach would be to add serialization to the handler (I.e; color-eyre), because the handler is the one who knows about things like spans, backtrace, etc, and it may be different based on handler what information is available.

A new method to the Handler trait would with a default-noop impl would then be exposed to access this handler-specific serialization.

To start with, we can add it to color-eyre and see how a structural serialization fairs there (basically struct-like serde with spantrace, backtrace, and error chain) and go from there

thewh1teagle commented 2 months ago

Would it be possible to add initial support for serialization first? This way, users won't need to implement their own types and deal with the overhead of getting serialization for errors. This PR has been pending for two months, and addressing this now would help reduce the waiting time for users. Once we have this minimal support in place, we can explore various improvements in future PRs/issues. Could you please clarify the benefits of waiting this long before merging?