Skip to content

Commit

Permalink
feat: support converting between anyhow::Error and eyre::Result
Browse files Browse the repository at this point in the history
  • Loading branch information
ten3roberts committed Jun 21, 2024
1 parent 907daa2 commit a663f0a
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 7 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ rust-version = "1.65.0"
indenter = "0.3.0"
once_cell = "1.18.0"
owo-colors = "4.0"
anyhow = "1.0"

[profile.dev.package.backtrace]
opt-level = 3
Expand Down
5 changes: 2 additions & 3 deletions eyre/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,22 @@ readme = { workspace = true }
rust-version = { workspace = true }

[features]
default = ["anyhow", "auto-install", "track-caller"]
anyhow = []
default = [ "auto-install", "track-caller"]
auto-install = []
track-caller = []

[dependencies]
indenter = { workspace = true }
once_cell = { workspace = true }
pyo3 = { version = "0.20", optional = true, default-features = false }
anyhow = { workspace = true, optional = true, default-features = false }

[dev-dependencies]
futures = { version = "0.3", default-features = false }
rustversion = "1.0"
thiserror = "1.0"
trybuild = { version = "=1.0.89", features = ["diff"] } # pinned due to MSRV
backtrace = "0.3.46"
anyhow = "1.0.28"
syn = { version = "2.0", features = ["full"] }
pyo3 = { version = "0.20", default-features = false, features = ["auto-initialize"] }

Expand Down
28 changes: 24 additions & 4 deletions eyre/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use core::mem::{self, ManuallyDrop};
use core::ptr::{self, NonNull};

use core::ops::{Deref, DerefMut};
use std::any::Any;

impl Report {
/// Create a new error object from any error type.
Expand Down Expand Up @@ -490,14 +491,33 @@ impl Report {

impl<E> From<E> for Report
where
E: StdError + Send + Sync + 'static,
E: 'static + Into<anyhow::Error>,

Check failure on line 494 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Check (stable)

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 494 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite (macOS-latest)

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 494 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite (ubuntu-latest)

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 494 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite (beta, --no-default-features --features auto-install)

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 494 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite (beta)

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 494 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite (beta, --no-default-features --features track-caller)

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 494 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite (beta, --features pyo3)

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 494 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite (nightly)

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 494 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite (beta, --no-default-features)

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 494 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite (nightly, --features pyo3)

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 494 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Miri

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 494 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite (--no-default-features)

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 494 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 494 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite (--no-default-features --features track-caller)

failed to resolve: use of undeclared crate or module `anyhow`
Result<(), E>: anyhow::Context<(), E>,

Check failure on line 495 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Check (stable)

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 495 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite (macOS-latest)

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 495 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite (ubuntu-latest)

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 495 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite (beta, --no-default-features --features auto-install)

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 495 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite (beta)

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 495 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite (beta, --no-default-features --features track-caller)

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 495 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite (beta, --features pyo3)

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 495 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite (nightly)

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 495 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite (beta, --no-default-features)

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 495 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite (nightly, --features pyo3)

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 495 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Miri

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 495 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite (--no-default-features)

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 495 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 495 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite (--no-default-features --features track-caller)

failed to resolve: use of undeclared crate or module `anyhow`
{
#[cfg_attr(track_caller, track_caller)]
fn from(error: E) -> Self {
Report::from_std(error)
fn from(value: E) -> Self {
let mut value = Some(value);
let e = &mut value as &mut dyn Any;

if let Some(e) = e.downcast_mut::<Option<anyhow::Error>>() {

Check failure on line 501 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Check (stable)

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 501 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite (macOS-latest)

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 501 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite (ubuntu-latest)

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 501 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite (beta, --no-default-features --features auto-install)

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 501 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite (beta)

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 501 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite (beta, --no-default-features --features track-caller)

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 501 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite (beta, --features pyo3)

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 501 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite (nightly)

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 501 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite (beta, --no-default-features)

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 501 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite (nightly, --features pyo3)

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 501 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Miri

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 501 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite (--no-default-features)

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 501 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite

failed to resolve: use of undeclared crate or module `anyhow`

Check failure on line 501 in eyre/src/error.rs

View workflow job for this annotation

GitHub Actions / Test Suite (--no-default-features --features track-caller)

failed to resolve: use of undeclared crate or module `anyhow`
let e: Box<dyn StdError + Send + Sync> = e.take().unwrap().into();
Report::from_boxed(e)
} else {
let e: Box<dyn StdError + Send + Sync> = value.take().unwrap().into().into();
Report::from_boxed(e)
}
}
}

// impl<E> From<E> for Report
// where
// E: StdError + Send + Sync + 'static,
// {
// #[cfg_attr(track_caller, track_caller)]
// fn from(error: E) -> Self {
// Report::from_std(error)
// }
// }

impl Deref for Report {
type Target = dyn StdError + Send + Sync + 'static;

Expand Down
55 changes: 55 additions & 0 deletions eyre/tests/test_anyhow.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use eyre::Report;
use std::fmt::Display;

#[derive(Debug)]
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
}
}

fn this_function_fails() -> anyhow::Result<()> {
use anyhow::Context;

Err(RootError).context("Ouch!").context("Anyhow context A")
}

fn bubble() -> eyre::Result<()> {
use anyhow::Context;
this_function_fails().context("Anyhow context B")?;

Ok(())
}

#[test]
fn anyhow_conversion() {
use eyre::WrapErr;
let error: Report = bubble().wrap_err("Eyre context").unwrap_err();

eprintln!("Error: {:?}", error);

let chain = error.chain().map(ToString::to_string).collect::<Vec<_>>();
assert_eq!(
chain,
[
"Eyre context",
// 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");
}

0 comments on commit a663f0a

Please sign in to comment.