-
Notifications
You must be signed in to change notification settings - Fork 18
Globally consistent error reporting formats #10
Comments
I'm not entirely sure if this is related, and how it might relate to rust-lang/rfcs#2895, but I'm currently trying to use tracing::Value error impl to render a logged e.g. let boxed_error: Box<dyn std::error::Error + 'static> = eyre::eyre!("Logged an eyre error using `tracing`!").into();
tracing::error!(error = &*boxed_error); My attempts to downcast If rust-lang/rfcs#2895 was stabilized, as I understand it, I should be able to access the extra metadata and render it again myself, but it might turn out differently to what it normally produced by |
The downcast won't work because the type that is actually used to create the The generic member access RFC would probably help in this case, though I'm sure how best to integrate it. The easiest way would be to have the same generic member access API exist on the I've not looked at how edit: a quick check at the docs shows that cc @hawkw |
I think this is currently my best plan but I don't really have an idea for how exactly to accomplish it let alone prototype it. Report Trait and ReporterThe idea here is to reverse the responsibility for reporting errors, much the same way
The described traits might look something like this: trait Report {
fn fmt(&self, reporter: &dyn fmt::Reporter, f: &mut fmt::Formatter<'_>) -> fmt::Result;
}
trait Reporter {
fn fmt_error(&self, error: &dyn Error, f: &mut fmt::Formatter<'_>) -> fmt::Result;
} The default impls would look something like this: default impl<D> Report for D
where
D: Debug,
{
fn fmt(&self, _reporter: &dyn Reporter, f: &mut Formatter<'_>) -> fmt::Result {
Debug::fmt(self, f)
}
}
default impl<E> Report for E
where
E: Error,
{
fn fmt(&self, reporter: &dyn Reporter, f: &mut Formatter<'_>) -> fmt::Result {
reporter.fmt_error(&self, f)
}
} By default most errors would never need to interact with this trait, but reporting types like The Unresolved QuestionsOnce we have this we still have to figure out how to design the Known Issues
|
Problem
Right now there's no easy way to ensure that all errors are printed with a consistent error report format such as via
eyre::Report
+color-eyre
. Errors that have not been converted to an error reporting type prior to panicking in functions likeunwrap
cannot then be correctly reported via the panic handler because the error is converted to a string and discarded. Even if it was not such as viapanic!(error)
directly you can only downcast to the exact type, so your error reporting hook would need an exhaustive list of all error types that it should try downcasting to, which is infeasible.Possible Solutions
Carry original type in payloads for panics and add support for casting from
&dyn Any
to&dyn Error
One possible approach to this would be to adjust panics to include the data they were created with in the payload along with the formatted message and then add support for somehow extracting error trait objects back out of those
&dyn Any
playloads. Ideally the solution for extracting trait objects of other kinds from&dyn Any
would not be specific to&dyn Error
. If we could create a language / library level feature for casting between arbitrary trait objects or even only from&dyn Any
to arbitrary trait objects that the underlying type also implements that would be ideal.@oli-obk has suggested the possibility of using linker shenanigans to accomplish this:
@DianaNites has pointed out that the following libraries may be useful as sources of prior art
Use new format traits and specialization to format errors in a more structured way
#10 (comment)
The text was updated successfully, but these errors were encountered: