mirror of
https://github.com/eyre-rs/eyre.git
synced 2025-09-28 21:41:58 +00:00
feat: basic backtrace propagation
This commit is contained in:
parent
29aec58099
commit
b52dba1323
@ -1,8 +1,9 @@
|
|||||||
#[cfg(backtrace)]
|
#[cfg(backtrace)]
|
||||||
pub(crate) use std::backtrace::Backtrace;
|
pub use std::backtrace::Backtrace;
|
||||||
|
|
||||||
#[cfg(not(backtrace))]
|
#[cfg(not(backtrace))]
|
||||||
pub(crate) enum Backtrace {}
|
#[derive(Debug)]
|
||||||
|
pub enum Backtrace {}
|
||||||
|
|
||||||
#[cfg(backtrace)]
|
#[cfg(backtrace)]
|
||||||
macro_rules! backtrace_if_absent {
|
macro_rules! backtrace_if_absent {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::Report;
|
use crate::{builder::ReportBuilder, Report};
|
||||||
|
|
||||||
/// Convert this result into an eyre [`Report`](crate::Report) result
|
/// Convert this result into an eyre [`Report`](crate::Report) result
|
||||||
///
|
///
|
||||||
@ -6,12 +6,7 @@ use crate::Report;
|
|||||||
/// [`Error`](std::error::Error) is not yet available.
|
/// [`Error`](std::error::Error) is not yet available.
|
||||||
pub trait IntoEyre<T> {
|
pub trait IntoEyre<T> {
|
||||||
/// Convert this result into an eyre [`Report`](crate::Report) result
|
/// Convert this result into an eyre [`Report`](crate::Report) result
|
||||||
fn into_eyre(self) -> crate::Result<T>
|
fn into_eyre(self) -> crate::Result<T>;
|
||||||
where
|
|
||||||
Self: Sized,
|
|
||||||
{
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See: [`IntoEyre`]
|
/// See: [`IntoEyre`]
|
||||||
@ -19,25 +14,27 @@ pub trait IntoEyre<T> {
|
|||||||
/// Error type automatically implements `into_eyre` for `Result<T, E>`
|
/// Error type automatically implements `into_eyre` for `Result<T, E>`
|
||||||
pub trait IntoEyreReport {
|
pub trait IntoEyreReport {
|
||||||
/// Convert this error into an eyre [`Report`](crate::Report)
|
/// Convert this error into an eyre [`Report`](crate::Report)
|
||||||
fn into_eyre_report(self) -> Report
|
#[track_caller]
|
||||||
where
|
fn into_eyre_report(self) -> Report;
|
||||||
Self: Sized,
|
|
||||||
{
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, E> IntoEyre<T> for Result<T, E>
|
impl<T, E> IntoEyre<T> for Result<T, E>
|
||||||
where
|
where
|
||||||
E: IntoEyreReport,
|
E: IntoEyreReport,
|
||||||
{
|
{
|
||||||
|
#[track_caller]
|
||||||
fn into_eyre(self) -> crate::Result<T> {
|
fn into_eyre(self) -> crate::Result<T> {
|
||||||
self.map_err(E::into_eyre_report)
|
// Use a manual match to keep backtrace
|
||||||
|
match self {
|
||||||
|
Ok(v) => Ok(v),
|
||||||
|
Err(err) => Err(err.into_eyre_report()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "anyhow-compat")]
|
#[cfg(feature = "anyhow-compat")]
|
||||||
impl IntoEyreReport for anyhow::Error {
|
impl IntoEyreReport for anyhow::Error {
|
||||||
|
#[track_caller]
|
||||||
fn into_eyre_report(self) -> Report
|
fn into_eyre_report(self) -> Report
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
@ -60,7 +57,13 @@ impl IntoEyreReport for anyhow::Error {
|
|||||||
.next()
|
.next()
|
||||||
.expect("Error chain contains at least one error");
|
.expect("Error chain contains at least one error");
|
||||||
|
|
||||||
let report = Report::msg(head.to_string());
|
#[cfg(backtrace)]
|
||||||
|
let report = ReportBuilder::default()
|
||||||
|
.with_backtrace(self.backtrace())
|
||||||
|
.msg(head.to_string());
|
||||||
|
|
||||||
|
#[cfg(not(backtrace))]
|
||||||
|
let report = ReportBuilder::default().msg(head.to_string());
|
||||||
// chai
|
// chai
|
||||||
// eprintln!("{:?}", chain.map(|v| v.to_string()).collect::<Vec<_>>());
|
// eprintln!("{:?}", chain.map(|v| v.to_string()).collect::<Vec<_>>());
|
||||||
|
|
||||||
|
@ -1,24 +1,64 @@
|
|||||||
use anyhow::Context;
|
use std::fmt::Display;
|
||||||
use eyre::WrapErr;
|
|
||||||
use eyre::{compat::IntoEyre, Report};
|
use eyre::{compat::IntoEyre, Report};
|
||||||
|
|
||||||
fn this_function_fails() -> anyhow::Result<()> {
|
#[derive(Debug)]
|
||||||
anyhow::bail!("Ouch!")
|
struct RootError;
|
||||||
|
|
||||||
|
impl Display for RootError {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "RootError")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl std::error::Error for RootError {
|
||||||
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "anyhow-compat")]
|
||||||
|
fn this_function_fails() -> anyhow::Result<()> {
|
||||||
|
use anyhow::Context;
|
||||||
|
|
||||||
|
Err(RootError).context("Ouch!").context("Anyhow context A")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "anyhow-compat")]
|
||||||
fn bubble() -> eyre::Result<()> {
|
fn bubble() -> eyre::Result<()> {
|
||||||
|
use anyhow::Context;
|
||||||
|
use eyre::WrapErr;
|
||||||
this_function_fails()
|
this_function_fails()
|
||||||
.context("Anyhow::context")
|
.context("Anyhow context B")
|
||||||
.into_eyre()
|
.into_eyre()
|
||||||
.wrap_err("Eyre::wrap_err")?;
|
.wrap_err("Eyre context A")?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "anyhow-compat")]
|
||||||
#[test]
|
#[test]
|
||||||
fn anyhow_conversion() {
|
fn anyhow_conversion() {
|
||||||
let error: Report = bubble().unwrap_err();
|
use eyre::WrapErr;
|
||||||
// let error = Report::msg("A").wrap_err("B").wrap_err("C");
|
let error: Report = bubble().wrap_err("Eyre context B").unwrap_err();
|
||||||
|
|
||||||
eprintln!("{error:?}");
|
eprintln!("{error:?}");
|
||||||
|
|
||||||
|
let chain = error.chain().map(ToString::to_string).collect::<Vec<_>>();
|
||||||
|
assert_eq!(
|
||||||
|
chain,
|
||||||
|
[
|
||||||
|
"Eyre context B",
|
||||||
|
"Eyre context A",
|
||||||
|
// Anyhow context
|
||||||
|
"Anyhow context B",
|
||||||
|
"Anyhow context A",
|
||||||
|
// Anyhow error
|
||||||
|
"Ouch!",
|
||||||
|
// Original concrete error, shows up in chain too
|
||||||
|
"RootError"
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
// let error = Report::msg("A").wrap_err("B").wrap_err("C");
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user