mirror of
https://github.com/eyre-rs/eyre.git
synced 2025-09-29 22:11:55 +00:00
Rename core types
This commit is contained in:
parent
bac602c301
commit
86da223cde
@ -1,17 +1,17 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "anyhow"
|
name = "eyre"
|
||||||
version = "1.0.26" # remember to update html_root_url
|
version = "1.0.26" # remember to update html_root_url
|
||||||
authors = ["David Tolnay <dtolnay@gmail.com>"]
|
authors = ["David Tolnay <dtolnay@gmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
description = "Flexible concrete Error type built on std::error::Error"
|
description = "Flexible concrete Error type built on std::error::Error"
|
||||||
repository = "https://github.com/dtolnay/anyhow"
|
repository = "https://github.com/dtolnay/eyre"
|
||||||
documentation = "https://docs.rs/anyhow"
|
documentation = "https://docs.rs/eyre"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
categories = ["rust-patterns"]
|
categories = ["rust-patterns"]
|
||||||
|
|
||||||
[badges]
|
[badges]
|
||||||
travis-ci = { repository = "dtolnay/anyhow" }
|
travis-ci = { repository = "dtolnay/eyre" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["std"]
|
default = ["std"]
|
||||||
|
28
README.md
28
README.md
@ -1,18 +1,18 @@
|
|||||||
Anyhow ¯\\\_(ツ)\_/¯
|
Anyhow ¯\\\_(ツ)\_/¯
|
||||||
=========================
|
=========================
|
||||||
|
|
||||||
[](https://travis-ci.com/dtolnay/anyhow)
|
[](https://travis-ci.com/dtolnay/eyre)
|
||||||
[](https://crates.io/crates/anyhow)
|
[](https://crates.io/crates/eyre)
|
||||||
[](https://docs.rs/anyhow)
|
[](https://docs.rs/eyre)
|
||||||
|
|
||||||
This library provides [`anyhow::Error`][Error], a trait object based error type
|
This library provides [`eyre::Error`][Error], a trait object based error type
|
||||||
for easy idiomatic error handling in Rust applications.
|
for easy idiomatic error handling in Rust applications.
|
||||||
|
|
||||||
[Error]: https://docs.rs/anyhow/1.0/anyhow/struct.Error.html
|
[Error]: https://docs.rs/eyre/1.0/eyre/struct.Error.html
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0"
|
eyre = "1.0"
|
||||||
```
|
```
|
||||||
|
|
||||||
*Compiler support: requires rustc 1.34+*
|
*Compiler support: requires rustc 1.34+*
|
||||||
@ -21,14 +21,14 @@ anyhow = "1.0"
|
|||||||
|
|
||||||
## Details
|
## Details
|
||||||
|
|
||||||
- Use `Result<T, anyhow::Error>`, or equivalently `anyhow::Result<T>`, as the
|
- Use `Result<T, eyre::Error>`, or equivalently `eyre::Result<T>`, as the
|
||||||
return type of any fallible function.
|
return type of any fallible function.
|
||||||
|
|
||||||
Within the function, use `?` to easily propagate any error that implements the
|
Within the function, use `?` to easily propagate any error that implements the
|
||||||
`std::error::Error` trait.
|
`std::error::Error` trait.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use anyhow::Result;
|
use eyre::Result;
|
||||||
|
|
||||||
fn get_cluster_info() -> Result<ClusterMap> {
|
fn get_cluster_info() -> Result<ClusterMap> {
|
||||||
let config = std::fs::read_to_string("cluster.json")?;
|
let config = std::fs::read_to_string("cluster.json")?;
|
||||||
@ -43,7 +43,7 @@ anyhow = "1.0"
|
|||||||
application was in the middle of.
|
application was in the middle of.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use anyhow::{Context, Result};
|
use eyre::{Context, Result};
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
...
|
...
|
||||||
@ -98,11 +98,11 @@ anyhow = "1.0"
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- One-off error messages can be constructed using the `anyhow!` macro, which
|
- One-off error messages can be constructed using the `eyre!` macro, which
|
||||||
supports string interpolation and produces an `anyhow::Error`.
|
supports string interpolation and produces an `eyre::Error`.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
return Err(anyhow!("Missing attribute: {}", missing));
|
return Err(eyre!("Missing attribute: {}", missing));
|
||||||
```
|
```
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
@ -115,7 +115,7 @@ Cargo.toml. A global allocator is required.
|
|||||||
|
|
||||||
```toml
|
```toml
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = { version = "1.0", default-features = false }
|
eyre = { version = "1.0", default-features = false }
|
||||||
```
|
```
|
||||||
|
|
||||||
Since the `?`-based error conversions would normally rely on the
|
Since the `?`-based error conversions would normally rely on the
|
||||||
@ -127,7 +127,7 @@ type inside a function that returns Anyhow's error type.
|
|||||||
|
|
||||||
## Comparison to failure
|
## Comparison to failure
|
||||||
|
|
||||||
The `anyhow::Error` type works something like `failure::Error`, but unlike
|
The `eyre::Error` type works something like `failure::Error`, but unlike
|
||||||
failure ours is built around the standard library's `std::error::Error` trait
|
failure ours is built around the standard library's `std::error::Error` trait
|
||||||
rather than a separate trait `failure::Fail`. The standard library has adopted
|
rather than a separate trait `failure::Fail`. The standard library has adopted
|
||||||
the necessary improvements for this to be possible as part of [RFC 2504].
|
the necessary improvements for this to be possible as part of [RFC 2504].
|
||||||
|
4
build.rs
4
build.rs
@ -5,7 +5,7 @@ use std::process::{Command, ExitStatus};
|
|||||||
|
|
||||||
// This code exercises the surface area that we expect of the std Backtrace
|
// This code exercises the surface area that we expect of the std Backtrace
|
||||||
// type. If the current toolchain is able to compile it, we go ahead and use
|
// type. If the current toolchain is able to compile it, we go ahead and use
|
||||||
// backtrace in anyhow.
|
// backtrace in eyre.
|
||||||
const PROBE: &str = r#"
|
const PROBE: &str = r#"
|
||||||
#![feature(backtrace)]
|
#![feature(backtrace)]
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
@ -51,7 +51,7 @@ fn compile_probe() -> Option<ExitStatus> {
|
|||||||
fs::write(&probefile, PROBE).ok()?;
|
fs::write(&probefile, PROBE).ok()?;
|
||||||
Command::new(rustc)
|
Command::new(rustc)
|
||||||
.arg("--edition=2018")
|
.arg("--edition=2018")
|
||||||
.arg("--crate-name=anyhow_build")
|
.arg("--crate-name=eyre_build")
|
||||||
.arg("--crate-type=lib")
|
.arg("--crate-type=lib")
|
||||||
.arg("--emit=metadata")
|
.arg("--emit=metadata")
|
||||||
.arg("--out-dir")
|
.arg("--out-dir")
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::error::ContextError;
|
use crate::error::ContextError;
|
||||||
use crate::{Context, Error, StdError};
|
use crate::{Context, ErrReport, StdError};
|
||||||
use core::convert::Infallible;
|
use core::convert::Infallible;
|
||||||
use core::fmt::{self, Debug, Display, Write};
|
use core::fmt::{self, Debug, Display, Write};
|
||||||
|
|
||||||
@ -10,7 +10,7 @@ mod ext {
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub trait StdError {
|
pub trait StdError {
|
||||||
fn ext_context<C>(self, context: C) -> Error
|
fn ext_context<C>(self, context: C) -> ErrReport
|
||||||
where
|
where
|
||||||
C: Display + Send + Sync + 'static;
|
C: Display + Send + Sync + 'static;
|
||||||
}
|
}
|
||||||
@ -20,17 +20,17 @@ mod ext {
|
|||||||
where
|
where
|
||||||
E: std::error::Error + Send + Sync + 'static,
|
E: std::error::Error + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
fn ext_context<C>(self, context: C) -> Error
|
fn ext_context<C>(self, context: C) -> ErrReport
|
||||||
where
|
where
|
||||||
C: Display + Send + Sync + 'static,
|
C: Display + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
let backtrace = backtrace_if_absent!(self);
|
let backtrace = backtrace_if_absent!(self);
|
||||||
Error::from_context(context, self, backtrace)
|
ErrReport::from_context(context, self, backtrace)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StdError for Error {
|
impl StdError for ErrReport {
|
||||||
fn ext_context<C>(self, context: C) -> Error
|
fn ext_context<C>(self, context: C) -> ErrReport
|
||||||
where
|
where
|
||||||
C: Display + Send + Sync + 'static,
|
C: Display + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
@ -43,14 +43,14 @@ impl<T, E> Context<T, E> for Result<T, E>
|
|||||||
where
|
where
|
||||||
E: ext::StdError + Send + Sync + 'static,
|
E: ext::StdError + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
fn context<C>(self, context: C) -> Result<T, Error>
|
fn context<C>(self, context: C) -> Result<T, ErrReport>
|
||||||
where
|
where
|
||||||
C: Display + Send + Sync + 'static,
|
C: Display + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
self.map_err(|error| error.ext_context(context))
|
self.map_err(|error| error.ext_context(context))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_context<C, F>(self, context: F) -> Result<T, Error>
|
fn with_context<C, F>(self, context: F) -> Result<T, ErrReport>
|
||||||
where
|
where
|
||||||
C: Display + Send + Sync + 'static,
|
C: Display + Send + Sync + 'static,
|
||||||
F: FnOnce() -> C,
|
F: FnOnce() -> C,
|
||||||
@ -62,7 +62,7 @@ where
|
|||||||
/// ```
|
/// ```
|
||||||
/// # type T = ();
|
/// # type T = ();
|
||||||
/// #
|
/// #
|
||||||
/// use anyhow::{Context, Result};
|
/// use eyre::{Context, Result};
|
||||||
///
|
///
|
||||||
/// fn maybe_get() -> Option<T> {
|
/// fn maybe_get() -> Option<T> {
|
||||||
/// # const IGNORE: &str = stringify! {
|
/// # const IGNORE: &str = stringify! {
|
||||||
@ -80,19 +80,19 @@ where
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
impl<T> Context<T, Infallible> for Option<T> {
|
impl<T> Context<T, Infallible> for Option<T> {
|
||||||
fn context<C>(self, context: C) -> Result<T, Error>
|
fn context<C>(self, context: C) -> Result<T, ErrReport>
|
||||||
where
|
where
|
||||||
C: Display + Send + Sync + 'static,
|
C: Display + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
self.ok_or_else(|| Error::from_display(context, backtrace!()))
|
self.ok_or_else(|| ErrReport::from_display(context, backtrace!()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_context<C, F>(self, context: F) -> Result<T, Error>
|
fn with_context<C, F>(self, context: F) -> Result<T, ErrReport>
|
||||||
where
|
where
|
||||||
C: Display + Send + Sync + 'static,
|
C: Display + Send + Sync + 'static,
|
||||||
F: FnOnce() -> C,
|
F: FnOnce() -> C,
|
||||||
{
|
{
|
||||||
self.ok_or_else(|| Error::from_display(context(), backtrace!()))
|
self.ok_or_else(|| ErrReport::from_display(context(), backtrace!()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C> StdError for ContextError<C, Error>
|
impl<C> StdError for ContextError<C, ErrReport>
|
||||||
where
|
where
|
||||||
C: Display,
|
C: Display,
|
||||||
{
|
{
|
||||||
|
108
src/error.rs
108
src/error.rs
@ -1,7 +1,7 @@
|
|||||||
use crate::alloc::Box;
|
use crate::alloc::Box;
|
||||||
use crate::backtrace::Backtrace;
|
use crate::backtrace::Backtrace;
|
||||||
use crate::chain::Chain;
|
use crate::chain::Chain;
|
||||||
use crate::{Error, StdError};
|
use crate::{ErrReport, StdError};
|
||||||
use core::any::TypeId;
|
use core::any::TypeId;
|
||||||
use core::fmt::{self, Debug, Display};
|
use core::fmt::{self, Debug, Display};
|
||||||
use core::mem::{self, ManuallyDrop};
|
use core::mem::{self, ManuallyDrop};
|
||||||
@ -10,10 +10,10 @@ use core::ptr::{self, NonNull};
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use core::ops::{Deref, DerefMut};
|
use core::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
impl Error {
|
impl ErrReport {
|
||||||
/// Create a new error object from any error type.
|
/// Create a new error object from any error type.
|
||||||
///
|
///
|
||||||
/// The error type must be threadsafe and `'static`, so that the `Error`
|
/// The error type must be threadsafe and `'static`, so that the `ErrReport`
|
||||||
/// will be as well.
|
/// will be as well.
|
||||||
///
|
///
|
||||||
/// If the error type does not provide a backtrace, a backtrace will be
|
/// If the error type does not provide a backtrace, a backtrace will be
|
||||||
@ -24,18 +24,18 @@ impl Error {
|
|||||||
E: StdError + Send + Sync + 'static,
|
E: StdError + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
let backtrace = backtrace_if_absent!(error);
|
let backtrace = backtrace_if_absent!(error);
|
||||||
Error::from_std(error, backtrace)
|
ErrReport::from_std(error, backtrace)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new error object from a printable error message.
|
/// Create a new error object from a printable error message.
|
||||||
///
|
///
|
||||||
/// If the argument implements std::error::Error, prefer `Error::new`
|
/// If the argument implements std::error::Error, prefer `ErrReport::new`
|
||||||
/// instead which preserves the underlying error's cause chain and
|
/// instead which preserves the underlying error's cause chain and
|
||||||
/// backtrace. If the argument may or may not implement std::error::Error
|
/// backtrace. If the argument may or may not implement std::error::Error
|
||||||
/// now or in the future, use `anyhow!(err)` which handles either way
|
/// now or in the future, use `eyre!(err)` which handles either way
|
||||||
/// correctly.
|
/// correctly.
|
||||||
///
|
///
|
||||||
/// `Error::msg("...")` is equivalent to `anyhow!("...")` but occasionally
|
/// `ErrReport::msg("...")` is equivalent to `eyre!("...")` but occasionally
|
||||||
/// convenient in places where a function is preferable over a macro, such
|
/// convenient in places where a function is preferable over a macro, such
|
||||||
/// as iterator or stream combinators:
|
/// as iterator or stream combinators:
|
||||||
///
|
///
|
||||||
@ -50,7 +50,7 @@ impl Error {
|
|||||||
/// #
|
/// #
|
||||||
/// # use ffi::{Input, Output};
|
/// # use ffi::{Input, Output};
|
||||||
/// #
|
/// #
|
||||||
/// use anyhow::{Error, Result};
|
/// use eyre::{ErrReport, Result};
|
||||||
/// use futures::stream::{Stream, StreamExt, TryStreamExt};
|
/// use futures::stream::{Stream, StreamExt, TryStreamExt};
|
||||||
///
|
///
|
||||||
/// async fn demo<S>(stream: S) -> Result<Vec<Output>>
|
/// async fn demo<S>(stream: S) -> Result<Vec<Output>>
|
||||||
@ -59,7 +59,7 @@ impl Error {
|
|||||||
/// {
|
/// {
|
||||||
/// stream
|
/// stream
|
||||||
/// .then(ffi::do_some_work) // returns Result<Output, &str>
|
/// .then(ffi::do_some_work) // returns Result<Output, &str>
|
||||||
/// .map_err(Error::msg)
|
/// .map_err(ErrReport::msg)
|
||||||
/// .try_collect()
|
/// .try_collect()
|
||||||
/// .await
|
/// .await
|
||||||
/// }
|
/// }
|
||||||
@ -68,7 +68,7 @@ impl Error {
|
|||||||
where
|
where
|
||||||
M: Display + Debug + Send + Sync + 'static,
|
M: Display + Debug + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
Error::from_adhoc(message, backtrace!())
|
ErrReport::from_adhoc(message, backtrace!())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
@ -87,7 +87,7 @@ impl Error {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Safety: passing vtable that operates on the right type E.
|
// Safety: passing vtable that operates on the right type E.
|
||||||
unsafe { Error::construct(error, vtable, backtrace) }
|
unsafe { ErrReport::construct(error, vtable, backtrace) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn from_adhoc<M>(message: M, backtrace: Option<Backtrace>) -> Self
|
pub(crate) fn from_adhoc<M>(message: M, backtrace: Option<Backtrace>) -> Self
|
||||||
@ -108,7 +108,7 @@ impl Error {
|
|||||||
|
|
||||||
// Safety: MessageError is repr(transparent) so it is okay for the
|
// Safety: MessageError is repr(transparent) so it is okay for the
|
||||||
// vtable to allow casting the MessageError<M> to M.
|
// vtable to allow casting the MessageError<M> to M.
|
||||||
unsafe { Error::construct(error, vtable, backtrace) }
|
unsafe { ErrReport::construct(error, vtable, backtrace) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn from_display<M>(message: M, backtrace: Option<Backtrace>) -> Self
|
pub(crate) fn from_display<M>(message: M, backtrace: Option<Backtrace>) -> Self
|
||||||
@ -129,7 +129,7 @@ impl Error {
|
|||||||
|
|
||||||
// Safety: DisplayError is repr(transparent) so it is okay for the
|
// Safety: DisplayError is repr(transparent) so it is okay for the
|
||||||
// vtable to allow casting the DisplayError<M> to M.
|
// vtable to allow casting the DisplayError<M> to M.
|
||||||
unsafe { Error::construct(error, vtable, backtrace) }
|
unsafe { ErrReport::construct(error, vtable, backtrace) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
@ -151,7 +151,7 @@ impl Error {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Safety: passing vtable that operates on the right type.
|
// Safety: passing vtable that operates on the right type.
|
||||||
unsafe { Error::construct(error, vtable, backtrace) }
|
unsafe { ErrReport::construct(error, vtable, backtrace) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
@ -173,7 +173,7 @@ impl Error {
|
|||||||
|
|
||||||
// Safety: BoxedError is repr(transparent) so it is okay for the vtable
|
// Safety: BoxedError is repr(transparent) so it is okay for the vtable
|
||||||
// to allow casting to Box<dyn StdError + Send + Sync>.
|
// to allow casting to Box<dyn StdError + Send + Sync>.
|
||||||
unsafe { Error::construct(error, vtable, backtrace) }
|
unsafe { ErrReport::construct(error, vtable, backtrace) }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Takes backtrace as argument rather than capturing it here so that the
|
// Takes backtrace as argument rather than capturing it here so that the
|
||||||
@ -202,7 +202,7 @@ impl Error {
|
|||||||
// caller rather than a builtin fat pointer vtable.
|
// caller rather than a builtin fat pointer vtable.
|
||||||
let erased = mem::transmute::<Box<ErrorImpl<E>>, Box<ErrorImpl<()>>>(inner);
|
let erased = mem::transmute::<Box<ErrorImpl<E>>, Box<ErrorImpl<()>>>(inner);
|
||||||
let inner = ManuallyDrop::new(erased);
|
let inner = ManuallyDrop::new(erased);
|
||||||
Error { inner }
|
ErrReport { inner }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wrap the error value with additional context.
|
/// Wrap the error value with additional context.
|
||||||
@ -232,7 +232,7 @@ impl Error {
|
|||||||
/// # }
|
/// # }
|
||||||
/// # }
|
/// # }
|
||||||
/// #
|
/// #
|
||||||
/// use anyhow::Result;
|
/// use eyre::Result;
|
||||||
/// use std::fs::File;
|
/// use std::fs::File;
|
||||||
/// use std::path::Path;
|
/// use std::path::Path;
|
||||||
///
|
///
|
||||||
@ -255,7 +255,7 @@ impl Error {
|
|||||||
/// "only the first {} lines of {} are valid",
|
/// "only the first {} lines of {} are valid",
|
||||||
/// error.line, path.as_ref().display(),
|
/// error.line, path.as_ref().display(),
|
||||||
/// );
|
/// );
|
||||||
/// anyhow::Error::new(error).context(context)
|
/// eyre::ErrReport::new(error).context(context)
|
||||||
/// })
|
/// })
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
@ -263,29 +263,29 @@ impl Error {
|
|||||||
where
|
where
|
||||||
C: Display + Send + Sync + 'static,
|
C: Display + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
let error: ContextError<C, Error> = ContextError {
|
let error: ContextError<C, ErrReport> = ContextError {
|
||||||
context,
|
context,
|
||||||
error: self,
|
error: self,
|
||||||
};
|
};
|
||||||
|
|
||||||
let vtable = &ErrorVTable {
|
let vtable = &ErrorVTable {
|
||||||
object_drop: object_drop::<ContextError<C, Error>>,
|
object_drop: object_drop::<ContextError<C, ErrReport>>,
|
||||||
object_ref: object_ref::<ContextError<C, Error>>,
|
object_ref: object_ref::<ContextError<C, ErrReport>>,
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
object_mut: object_mut::<ContextError<C, Error>>,
|
object_mut: object_mut::<ContextError<C, ErrReport>>,
|
||||||
object_boxed: object_boxed::<ContextError<C, Error>>,
|
object_boxed: object_boxed::<ContextError<C, ErrReport>>,
|
||||||
object_downcast: context_chain_downcast::<C>,
|
object_downcast: context_chain_downcast::<C>,
|
||||||
object_drop_rest: context_chain_drop_rest::<C>,
|
object_drop_rest: context_chain_drop_rest::<C>,
|
||||||
};
|
};
|
||||||
|
|
||||||
// As the cause is anyhow::Error, we already have a backtrace for it.
|
// As the cause is eyre::ErrReport, we already have a backtrace for it.
|
||||||
let backtrace = None;
|
let backtrace = None;
|
||||||
|
|
||||||
// Safety: passing vtable that operates on the right type.
|
// Safety: passing vtable that operates on the right type.
|
||||||
unsafe { Error::construct(error, vtable, backtrace) }
|
unsafe { ErrReport::construct(error, vtable, backtrace) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the backtrace for this Error.
|
/// Get the backtrace for this ErrReport.
|
||||||
///
|
///
|
||||||
/// Backtraces are only available on the nightly channel. Tracking issue:
|
/// Backtraces are only available on the nightly channel. Tracking issue:
|
||||||
/// [rust-lang/rust#53487][tracking].
|
/// [rust-lang/rust#53487][tracking].
|
||||||
@ -301,7 +301,7 @@ impl Error {
|
|||||||
self.inner.backtrace()
|
self.inner.backtrace()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An iterator of the chain of source errors contained by this Error.
|
/// An iterator of the chain of source errors contained by this ErrReport.
|
||||||
///
|
///
|
||||||
/// This iterator will visit every error in the cause chain of this error
|
/// This iterator will visit every error in the cause chain of this error
|
||||||
/// object, beginning with the error that this error object was created
|
/// object, beginning with the error that this error object was created
|
||||||
@ -310,10 +310,10 @@ impl Error {
|
|||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use anyhow::Error;
|
/// use eyre::ErrReport;
|
||||||
/// use std::io;
|
/// use std::io;
|
||||||
///
|
///
|
||||||
/// pub fn underlying_io_error_kind(error: &Error) -> Option<io::ErrorKind> {
|
/// pub fn underlying_io_error_kind(error: &ErrReport) -> Option<io::ErrorKind> {
|
||||||
/// for cause in error.chain() {
|
/// for cause in error.chain() {
|
||||||
/// if let Some(io_error) = cause.downcast_ref::<io::Error>() {
|
/// if let Some(io_error) = cause.downcast_ref::<io::Error>() {
|
||||||
/// return Some(io_error.kind());
|
/// return Some(io_error.kind());
|
||||||
@ -331,7 +331,7 @@ impl Error {
|
|||||||
/// cause's cause etc.
|
/// cause's cause etc.
|
||||||
///
|
///
|
||||||
/// The root cause is the last error in the iterator produced by
|
/// The root cause is the last error in the iterator produced by
|
||||||
/// [`chain()`][Error::chain].
|
/// [`chain()`][ErrReport::chain].
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub fn root_cause(&self) -> &(dyn StdError + 'static) {
|
pub fn root_cause(&self) -> &(dyn StdError + 'static) {
|
||||||
let mut chain = self.chain();
|
let mut chain = self.chain();
|
||||||
@ -379,7 +379,7 @@ impl Error {
|
|||||||
let error = ptr::read(addr.cast::<E>().as_ptr());
|
let error = ptr::read(addr.cast::<E>().as_ptr());
|
||||||
|
|
||||||
// Read Box<ErrorImpl<()>> from self. Can't move it out because
|
// Read Box<ErrorImpl<()>> from self. Can't move it out because
|
||||||
// Error has a Drop impl which we want to not run.
|
// ErrReport has a Drop impl which we want to not run.
|
||||||
let inner = ptr::read(&outer.inner);
|
let inner = ptr::read(&outer.inner);
|
||||||
let erased = ManuallyDrop::into_inner(inner);
|
let erased = ManuallyDrop::into_inner(inner);
|
||||||
|
|
||||||
@ -395,7 +395,7 @@ impl Error {
|
|||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # use anyhow::anyhow;
|
/// # use eyre::eyre;
|
||||||
/// # use std::fmt::{self, Display};
|
/// # use std::fmt::{self, Display};
|
||||||
/// # use std::task::Poll;
|
/// # use std::task::Poll;
|
||||||
/// #
|
/// #
|
||||||
@ -414,7 +414,7 @@ impl Error {
|
|||||||
/// #
|
/// #
|
||||||
/// # const REDACTED_CONTENT: () = ();
|
/// # const REDACTED_CONTENT: () = ();
|
||||||
/// #
|
/// #
|
||||||
/// # let error = anyhow!("...");
|
/// # let error = eyre!("...");
|
||||||
/// # let root_cause = &error;
|
/// # let root_cause = &error;
|
||||||
/// #
|
/// #
|
||||||
/// # let ret =
|
/// # let ret =
|
||||||
@ -455,18 +455,18 @@ impl Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<E> From<E> for Error
|
impl<E> From<E> for ErrReport
|
||||||
where
|
where
|
||||||
E: StdError + Send + Sync + 'static,
|
E: StdError + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
fn from(error: E) -> Self {
|
fn from(error: E) -> Self {
|
||||||
let backtrace = backtrace_if_absent!(error);
|
let backtrace = backtrace_if_absent!(error);
|
||||||
Error::from_std(error, backtrace)
|
ErrReport::from_std(error, backtrace)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl Deref for Error {
|
impl Deref for ErrReport {
|
||||||
type Target = dyn StdError + Send + Sync + 'static;
|
type Target = dyn StdError + Send + Sync + 'static;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
@ -475,25 +475,25 @@ impl Deref for Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl DerefMut for Error {
|
impl DerefMut for ErrReport {
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
self.inner.error_mut()
|
self.inner.error_mut()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Error {
|
impl Display for ErrReport {
|
||||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
self.inner.display(formatter)
|
self.inner.display(formatter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for Error {
|
impl Debug for ErrReport {
|
||||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
self.inner.debug(formatter)
|
self.inner.debug(formatter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for Error {
|
impl Drop for ErrReport {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
// Read Box<ErrorImpl<()>> from self.
|
// Read Box<ErrorImpl<()>> from self.
|
||||||
@ -622,24 +622,24 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>.
|
// Safety: requires layout of *e to match ErrorImpl<ContextError<C, ErrReport>>.
|
||||||
unsafe fn context_chain_downcast<C>(e: &ErrorImpl<()>, target: TypeId) -> Option<NonNull<()>>
|
unsafe fn context_chain_downcast<C>(e: &ErrorImpl<()>, target: TypeId) -> Option<NonNull<()>>
|
||||||
where
|
where
|
||||||
C: 'static,
|
C: 'static,
|
||||||
{
|
{
|
||||||
if TypeId::of::<C>() == target {
|
if TypeId::of::<C>() == target {
|
||||||
let unerased = e as *const ErrorImpl<()> as *const ErrorImpl<ContextError<C, Error>>;
|
let unerased = e as *const ErrorImpl<()> as *const ErrorImpl<ContextError<C, ErrReport>>;
|
||||||
let addr = &(*unerased)._object.context as *const C as *mut ();
|
let addr = &(*unerased)._object.context as *const C as *mut ();
|
||||||
Some(NonNull::new_unchecked(addr))
|
Some(NonNull::new_unchecked(addr))
|
||||||
} else {
|
} else {
|
||||||
// Recurse down the context chain per the inner error's vtable.
|
// Recurse down the context chain per the inner error's vtable.
|
||||||
let unerased = e as *const ErrorImpl<()> as *const ErrorImpl<ContextError<C, Error>>;
|
let unerased = e as *const ErrorImpl<()> as *const ErrorImpl<ContextError<C, ErrReport>>;
|
||||||
let source = &(*unerased)._object.error;
|
let source = &(*unerased)._object.error;
|
||||||
(source.inner.vtable.object_downcast)(&source.inner, target)
|
(source.inner.vtable.object_downcast)(&source.inner, target)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>.
|
// Safety: requires layout of *e to match ErrorImpl<ContextError<C, ErrReport>>.
|
||||||
unsafe fn context_chain_drop_rest<C>(e: Box<ErrorImpl<()>>, target: TypeId)
|
unsafe fn context_chain_drop_rest<C>(e: Box<ErrorImpl<()>>, target: TypeId)
|
||||||
where
|
where
|
||||||
C: 'static,
|
C: 'static,
|
||||||
@ -649,14 +649,14 @@ where
|
|||||||
if TypeId::of::<C>() == target {
|
if TypeId::of::<C>() == target {
|
||||||
let unerased = mem::transmute::<
|
let unerased = mem::transmute::<
|
||||||
Box<ErrorImpl<()>>,
|
Box<ErrorImpl<()>>,
|
||||||
Box<ErrorImpl<ContextError<ManuallyDrop<C>, Error>>>,
|
Box<ErrorImpl<ContextError<ManuallyDrop<C>, ErrReport>>>,
|
||||||
>(e);
|
>(e);
|
||||||
// Drop the entire rest of the data structure rooted in the next Error.
|
// Drop the entire rest of the data structure rooted in the next ErrReport.
|
||||||
drop(unerased);
|
drop(unerased);
|
||||||
} else {
|
} else {
|
||||||
let unerased = mem::transmute::<
|
let unerased = mem::transmute::<
|
||||||
Box<ErrorImpl<()>>,
|
Box<ErrorImpl<()>>,
|
||||||
Box<ErrorImpl<ContextError<C, ManuallyDrop<Error>>>>,
|
Box<ErrorImpl<ContextError<C, ManuallyDrop<ErrReport>>>>,
|
||||||
>(e);
|
>(e);
|
||||||
// Read out a ManuallyDrop<Box<ErrorImpl<()>>> from the next error.
|
// Read out a ManuallyDrop<Box<ErrorImpl<()>>> from the next error.
|
||||||
let inner = ptr::read(&unerased._object.error.inner);
|
let inner = ptr::read(&unerased._object.error.inner);
|
||||||
@ -756,12 +756,12 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Error> for Box<dyn StdError + Send + Sync + 'static> {
|
impl From<ErrReport> for Box<dyn StdError + Send + Sync + 'static> {
|
||||||
fn from(error: Error) -> Self {
|
fn from(error: ErrReport) -> Self {
|
||||||
let outer = ManuallyDrop::new(error);
|
let outer = ManuallyDrop::new(error);
|
||||||
unsafe {
|
unsafe {
|
||||||
// Read Box<ErrorImpl<()>> from error. Can't move it out because
|
// Read Box<ErrorImpl<()>> from error. Can't move it out because
|
||||||
// Error has a Drop impl which we want to not run.
|
// ErrReport has a Drop impl which we want to not run.
|
||||||
let inner = ptr::read(&outer.inner);
|
let inner = ptr::read(&outer.inner);
|
||||||
let erased = ManuallyDrop::into_inner(inner);
|
let erased = ManuallyDrop::into_inner(inner);
|
||||||
|
|
||||||
@ -772,21 +772,21 @@ impl From<Error> for Box<dyn StdError + Send + Sync + 'static> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Error> for Box<dyn StdError + 'static> {
|
impl From<ErrReport> for Box<dyn StdError + 'static> {
|
||||||
fn from(error: Error) -> Self {
|
fn from(error: ErrReport) -> Self {
|
||||||
Box::<dyn StdError + Send + Sync>::from(error)
|
Box::<dyn StdError + Send + Sync>::from(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl AsRef<dyn StdError + Send + Sync> for Error {
|
impl AsRef<dyn StdError + Send + Sync> for ErrReport {
|
||||||
fn as_ref(&self) -> &(dyn StdError + Send + Sync + 'static) {
|
fn as_ref(&self) -> &(dyn StdError + Send + Sync + 'static) {
|
||||||
&**self
|
&**self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl AsRef<dyn StdError> for Error {
|
impl AsRef<dyn StdError> for ErrReport {
|
||||||
fn as_ref(&self) -> &(dyn StdError + 'static) {
|
fn as_ref(&self) -> &(dyn StdError + 'static) {
|
||||||
&**self
|
&**self
|
||||||
}
|
}
|
||||||
|
46
src/kind.rs
46
src/kind.rs
@ -1,50 +1,50 @@
|
|||||||
// Tagged dispatch mechanism for resolving the behavior of `anyhow!($expr)`.
|
// Tagged dispatch mechanism for resolving the behavior of `eyre!($expr)`.
|
||||||
//
|
//
|
||||||
// When anyhow! is given a single expr argument to turn into anyhow::Error, we
|
// When eyre! is given a single expr argument to turn into eyre::ErrReport, we
|
||||||
// want the resulting Error to pick up the input's implementation of source()
|
// want the resulting ErrReport to pick up the input's implementation of source()
|
||||||
// and backtrace() if it has a std::error::Error impl, otherwise require nothing
|
// and backtrace() if it has a std::error::Error impl, otherwise require nothing
|
||||||
// more than Display and Debug.
|
// more than Display and Debug.
|
||||||
//
|
//
|
||||||
// Expressed in terms of specialization, we want something like:
|
// Expressed in terms of specialization, we want something like:
|
||||||
//
|
//
|
||||||
// trait AnyhowNew {
|
// trait EyreNew {
|
||||||
// fn new(self) -> Error;
|
// fn new(self) -> ErrReport;
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// impl<T> AnyhowNew for T
|
// impl<T> EyreNew for T
|
||||||
// where
|
// where
|
||||||
// T: Display + Debug + Send + Sync + 'static,
|
// T: Display + Debug + Send + Sync + 'static,
|
||||||
// {
|
// {
|
||||||
// default fn new(self) -> Error {
|
// default fn new(self) -> ErrReport {
|
||||||
// /* no std error impl */
|
// /* no std error impl */
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// impl<T> AnyhowNew for T
|
// impl<T> EyreNew for T
|
||||||
// where
|
// where
|
||||||
// T: std::error::Error + Send + Sync + 'static,
|
// T: std::error::Error + Send + Sync + 'static,
|
||||||
// {
|
// {
|
||||||
// fn new(self) -> Error {
|
// fn new(self) -> ErrReport {
|
||||||
// /* use std error's source() and backtrace() */
|
// /* use std error's source() and backtrace() */
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// Since specialization is not stable yet, instead we rely on autoref behavior
|
// Since specialization is not stable yet, instead we rely on autoref behavior
|
||||||
// of method resolution to perform tagged dispatch. Here we have two traits
|
// of method resolution to perform tagged dispatch. Here we have two traits
|
||||||
// AdhocKind and TraitKind that both have an anyhow_kind() method. AdhocKind is
|
// AdhocKind and TraitKind that both have an eyre_kind() method. AdhocKind is
|
||||||
// implemented whether or not the caller's type has a std error impl, while
|
// implemented whether or not the caller's type has a std error impl, while
|
||||||
// TraitKind is implemented only when a std error impl does exist. The ambiguity
|
// TraitKind is implemented only when a std error impl does exist. The ambiguity
|
||||||
// is resolved by AdhocKind requiring an extra autoref so that it has lower
|
// is resolved by AdhocKind requiring an extra autoref so that it has lower
|
||||||
// precedence.
|
// precedence.
|
||||||
//
|
//
|
||||||
// The anyhow! macro will set up the call in this form:
|
// The eyre! macro will set up the call in this form:
|
||||||
//
|
//
|
||||||
// #[allow(unused_imports)]
|
// #[allow(unused_imports)]
|
||||||
// use $crate::private::{AdhocKind, TraitKind};
|
// use $crate::private::{AdhocKind, TraitKind};
|
||||||
// let error = $msg;
|
// let error = $msg;
|
||||||
// (&error).anyhow_kind().new(error)
|
// (&error).eyre_kind().new(error)
|
||||||
|
|
||||||
use crate::Error;
|
use crate::ErrReport;
|
||||||
use core::fmt::{Debug, Display};
|
use core::fmt::{Debug, Display};
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
@ -57,7 +57,7 @@ pub struct Adhoc;
|
|||||||
|
|
||||||
pub trait AdhocKind: Sized {
|
pub trait AdhocKind: Sized {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn anyhow_kind(&self) -> Adhoc {
|
fn eyre_kind(&self) -> Adhoc {
|
||||||
Adhoc
|
Adhoc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -65,11 +65,11 @@ pub trait AdhocKind: Sized {
|
|||||||
impl<T> AdhocKind for &T where T: ?Sized + Display + Debug + Send + Sync + 'static {}
|
impl<T> AdhocKind for &T where T: ?Sized + Display + Debug + Send + Sync + 'static {}
|
||||||
|
|
||||||
impl Adhoc {
|
impl Adhoc {
|
||||||
pub fn new<M>(self, message: M) -> Error
|
pub fn new<M>(self, message: M) -> ErrReport
|
||||||
where
|
where
|
||||||
M: Display + Debug + Send + Sync + 'static,
|
M: Display + Debug + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
Error::from_adhoc(message, backtrace!())
|
ErrReport::from_adhoc(message, backtrace!())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,17 +77,17 @@ pub struct Trait;
|
|||||||
|
|
||||||
pub trait TraitKind: Sized {
|
pub trait TraitKind: Sized {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn anyhow_kind(&self) -> Trait {
|
fn eyre_kind(&self) -> Trait {
|
||||||
Trait
|
Trait
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> TraitKind for E where E: Into<Error> {}
|
impl<E> TraitKind for E where E: Into<ErrReport> {}
|
||||||
|
|
||||||
impl Trait {
|
impl Trait {
|
||||||
pub fn new<E>(self, error: E) -> Error
|
pub fn new<E>(self, error: E) -> ErrReport
|
||||||
where
|
where
|
||||||
E: Into<Error>,
|
E: Into<ErrReport>,
|
||||||
{
|
{
|
||||||
error.into()
|
error.into()
|
||||||
}
|
}
|
||||||
@ -99,7 +99,7 @@ pub struct Boxed;
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub trait BoxedKind: Sized {
|
pub trait BoxedKind: Sized {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn anyhow_kind(&self) -> Boxed {
|
fn eyre_kind(&self) -> Boxed {
|
||||||
Boxed
|
Boxed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,8 +109,8 @@ impl BoxedKind for Box<dyn StdError + Send + Sync> {}
|
|||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl Boxed {
|
impl Boxed {
|
||||||
pub fn new(self, error: Box<dyn StdError + Send + Sync>) -> Error {
|
pub fn new(self, error: Box<dyn StdError + Send + Sync>) -> ErrReport {
|
||||||
let backtrace = backtrace_if_absent!(error);
|
let backtrace = backtrace_if_absent!(error);
|
||||||
Error::from_boxed(error, backtrace)
|
ErrReport::from_boxed(error, backtrace)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
98
src/lib.rs
98
src/lib.rs
@ -1,15 +1,15 @@
|
|||||||
//! This library provides [`anyhow::Error`][Error], a trait object based error
|
//! This library provides [`eyre::ErrReport`][ErrReport], a trait object based error
|
||||||
//! type for easy idiomatic error handling in Rust applications.
|
//! type for easy idiomatic error handling in Rust applications.
|
||||||
//!
|
//!
|
||||||
//! <br>
|
//! <br>
|
||||||
//!
|
//!
|
||||||
//! # Details
|
//! # Details
|
||||||
//!
|
//!
|
||||||
//! - Use `Result<T, anyhow::Error>`, or equivalently `anyhow::Result<T>`, as
|
//! - Use `Result<T, eyre::ErrReport>`, or equivalently `eyre::Result<T>`, as
|
||||||
//! the return type of any fallible function.
|
//! the return type of any fallible function.
|
||||||
//!
|
//!
|
||||||
//! Within the function, use `?` to easily propagate any error that implements
|
//! Within the function, use `?` to easily propagate any error that implements
|
||||||
//! the `std::error::Error` trait.
|
//! the `std::error::ErrReport` trait.
|
||||||
//!
|
//!
|
||||||
//! ```
|
//! ```
|
||||||
//! # pub trait Deserialize {}
|
//! # pub trait Deserialize {}
|
||||||
@ -27,7 +27,7 @@
|
|||||||
//! #
|
//! #
|
||||||
//! # impl Deserialize for ClusterMap {}
|
//! # impl Deserialize for ClusterMap {}
|
||||||
//! #
|
//! #
|
||||||
//! use anyhow::Result;
|
//! use eyre::Result;
|
||||||
//!
|
//!
|
||||||
//! fn get_cluster_info() -> Result<ClusterMap> {
|
//! fn get_cluster_info() -> Result<ClusterMap> {
|
||||||
//! let config = std::fs::read_to_string("cluster.json")?;
|
//! let config = std::fs::read_to_string("cluster.json")?;
|
||||||
@ -52,7 +52,7 @@
|
|||||||
//! # }
|
//! # }
|
||||||
//! # }
|
//! # }
|
||||||
//! #
|
//! #
|
||||||
//! use anyhow::{Context, Result};
|
//! use eyre::{Context, Result};
|
||||||
//!
|
//!
|
||||||
//! fn main() -> Result<()> {
|
//! fn main() -> Result<()> {
|
||||||
//! # return Ok(());
|
//! # return Ok(());
|
||||||
@ -88,7 +88,7 @@
|
|||||||
//! mutable reference as needed.
|
//! mutable reference as needed.
|
||||||
//!
|
//!
|
||||||
//! ```
|
//! ```
|
||||||
//! # use anyhow::anyhow;
|
//! # use eyre::eyre;
|
||||||
//! # use std::fmt::{self, Display};
|
//! # use std::fmt::{self, Display};
|
||||||
//! # use std::task::Poll;
|
//! # use std::task::Poll;
|
||||||
//! #
|
//! #
|
||||||
@ -107,7 +107,7 @@
|
|||||||
//! #
|
//! #
|
||||||
//! # const REDACTED_CONTENT: () = ();
|
//! # const REDACTED_CONTENT: () = ();
|
||||||
//! #
|
//! #
|
||||||
//! # let error = anyhow!("...");
|
//! # let error = eyre!("...");
|
||||||
//! # let root_cause = &error;
|
//! # let root_cause = &error;
|
||||||
//! #
|
//! #
|
||||||
//! # let ret =
|
//! # let ret =
|
||||||
@ -146,15 +146,15 @@
|
|||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! - One-off error messages can be constructed using the `anyhow!` macro, which
|
//! - One-off error messages can be constructed using the `eyre!` macro, which
|
||||||
//! supports string interpolation and produces an `anyhow::Error`.
|
//! supports string interpolation and produces an `eyre::ErrReport`.
|
||||||
//!
|
//!
|
||||||
//! ```
|
//! ```
|
||||||
//! # use anyhow::{anyhow, Result};
|
//! # use eyre::{eyre, Result};
|
||||||
//! #
|
//! #
|
||||||
//! # fn demo() -> Result<()> {
|
//! # fn demo() -> Result<()> {
|
||||||
//! # let missing = "...";
|
//! # let missing = "...";
|
||||||
//! return Err(anyhow!("Missing attribute: {}", missing));
|
//! return Err(eyre!("Missing attribute: {}", missing));
|
||||||
//! # Ok(())
|
//! # Ok(())
|
||||||
//! # }
|
//! # }
|
||||||
//! ```
|
//! ```
|
||||||
@ -169,15 +169,15 @@
|
|||||||
//!
|
//!
|
||||||
//! ```toml
|
//! ```toml
|
||||||
//! [dependencies]
|
//! [dependencies]
|
||||||
//! anyhow = { version = "1.0", default-features = false }
|
//! eyre = { version = "1.0", default-features = false }
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! Since the `?`-based error conversions would normally rely on the
|
//! Since the `?`-based error conversions would normally rely on the
|
||||||
//! `std::error::Error` trait which is only available through std, no_std mode
|
//! `std::error::ErrReport` trait which is only available through std, no_std mode
|
||||||
//! will require an explicit `.map_err(Error::msg)` when working with a
|
//! will require an explicit `.map_err(ErrReport::msg)` when working with a
|
||||||
//! non-Anyhow error type inside a function that returns Anyhow's error type.
|
//! non-Anyhow error type inside a function that returns Anyhow's error type.
|
||||||
|
|
||||||
#![doc(html_root_url = "https://docs.rs/anyhow/1.0.26")]
|
#![doc(html_root_url = "https://docs.rs/eyre/1.0.26")]
|
||||||
#![cfg_attr(backtrace, feature(backtrace))]
|
#![cfg_attr(backtrace, feature(backtrace))]
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
#![allow(
|
#![allow(
|
||||||
@ -225,17 +225,17 @@ trait StdError: Debug + Display {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub use anyhow as format_err;
|
pub use eyre as format_err;
|
||||||
|
|
||||||
/// The `Error` type, a wrapper around a dynamic error type.
|
/// The `ErrReport` type, a wrapper around a dynamic error type.
|
||||||
///
|
///
|
||||||
/// `Error` works a lot like `Box<dyn std::error::Error>`, but with these
|
/// `ErrReport` works a lot like `Box<dyn std::error::Error>`, but with these
|
||||||
/// differences:
|
/// differences:
|
||||||
///
|
///
|
||||||
/// - `Error` requires that the error is `Send`, `Sync`, and `'static`.
|
/// - `ErrReport` requires that the error is `Send`, `Sync`, and `'static`.
|
||||||
/// - `Error` guarantees that a backtrace is available, even if the underlying
|
/// - `ErrReport` guarantees that a backtrace is available, even if the underlying
|
||||||
/// error type does not provide one.
|
/// error type does not provide one.
|
||||||
/// - `Error` is represented as a narrow pointer — exactly one word in
|
/// - `ErrReport` is represented as a narrow pointer — exactly one word in
|
||||||
/// size instead of two.
|
/// size instead of two.
|
||||||
///
|
///
|
||||||
/// <br>
|
/// <br>
|
||||||
@ -245,13 +245,13 @@ pub use anyhow as format_err;
|
|||||||
/// When you print an error object using "{}" or to_string(), only the outermost
|
/// When you print an error object using "{}" or to_string(), only the outermost
|
||||||
/// underlying error or context is printed, not any of the lower level causes.
|
/// underlying error or context is printed, not any of the lower level causes.
|
||||||
/// This is exactly as if you had called the Display impl of the error from
|
/// This is exactly as if you had called the Display impl of the error from
|
||||||
/// which you constructed your anyhow::Error.
|
/// which you constructed your eyre::ErrReport.
|
||||||
///
|
///
|
||||||
/// ```console
|
/// ```console
|
||||||
/// Failed to read instrs from ./path/to/instrs.json
|
/// Failed to read instrs from ./path/to/instrs.json
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// To print causes as well using anyhow's default formatting of causes, use the
|
/// To print causes as well using eyre's default formatting of causes, use the
|
||||||
/// alternate selector "{:#}".
|
/// alternate selector "{:#}".
|
||||||
///
|
///
|
||||||
/// ```console
|
/// ```console
|
||||||
@ -269,12 +269,12 @@ pub use anyhow as format_err;
|
|||||||
/// No such file or directory (os error 2)
|
/// No such file or directory (os error 2)
|
||||||
///
|
///
|
||||||
/// Stack backtrace:
|
/// Stack backtrace:
|
||||||
/// 0: <E as anyhow::context::ext::StdError>::ext_context
|
/// 0: <E as eyre::context::ext::StdError>::ext_context
|
||||||
/// at /git/anyhow/src/backtrace.rs:26
|
/// at /git/eyre/src/backtrace.rs:26
|
||||||
/// 1: core::result::Result<T,E>::map_err
|
/// 1: core::result::Result<T,E>::map_err
|
||||||
/// at /git/rustc/src/libcore/result.rs:596
|
/// at /git/rustc/src/libcore/result.rs:596
|
||||||
/// 2: anyhow::context::<impl anyhow::Context<T,E> for core::result::Result<T,E>>::with_context
|
/// 2: eyre::context::<impl eyre::Context<T,E> for core::result::Result<T,E>>::with_context
|
||||||
/// at /git/anyhow/src/context.rs:58
|
/// at /git/eyre/src/context.rs:58
|
||||||
/// 3: testing::main
|
/// 3: testing::main
|
||||||
/// at src/main.rs:5
|
/// at src/main.rs:5
|
||||||
/// 4: std::rt::lang_start
|
/// 4: std::rt::lang_start
|
||||||
@ -302,7 +302,7 @@ pub use anyhow as format_err;
|
|||||||
/// like this:
|
/// like this:
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use anyhow::{Context, Result};
|
/// use eyre::{Context, Result};
|
||||||
///
|
///
|
||||||
/// fn main() {
|
/// fn main() {
|
||||||
/// if let Err(err) = try_main() {
|
/// if let Err(err) = try_main() {
|
||||||
@ -319,21 +319,21 @@ pub use anyhow as format_err;
|
|||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub struct Error {
|
pub struct ErrReport {
|
||||||
inner: ManuallyDrop<Box<ErrorImpl<()>>>,
|
inner: ManuallyDrop<Box<ErrorImpl<()>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Iterator of a chain of source errors.
|
/// Iterator of a chain of source errors.
|
||||||
///
|
///
|
||||||
/// This type is the iterator returned by [`Error::chain`].
|
/// This type is the iterator returned by [`ErrReport::chain`].
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use anyhow::Error;
|
/// use eyre::ErrReport;
|
||||||
/// use std::io;
|
/// use std::io;
|
||||||
///
|
///
|
||||||
/// pub fn underlying_io_error_kind(error: &Error) -> Option<io::ErrorKind> {
|
/// pub fn underlying_io_error_kind(error: &ErrReport) -> Option<io::ErrorKind> {
|
||||||
/// for cause in error.chain() {
|
/// for cause in error.chain() {
|
||||||
/// if let Some(io_error) = cause.downcast_ref::<io::Error>() {
|
/// if let Some(io_error) = cause.downcast_ref::<io::Error>() {
|
||||||
/// return Some(io_error.kind());
|
/// return Some(io_error.kind());
|
||||||
@ -354,14 +354,14 @@ pub struct Chain<'a> {
|
|||||||
/// for `fn main`; if you do, failures will be printed along with any
|
/// for `fn main`; if you do, failures will be printed along with any
|
||||||
/// [context][Context] and a backtrace if one was captured.
|
/// [context][Context] and a backtrace if one was captured.
|
||||||
///
|
///
|
||||||
/// `anyhow::Result` may be used with one *or* two type parameters.
|
/// `eyre::Result` may be used with one *or* two type parameters.
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use anyhow::Result;
|
/// use eyre::Result;
|
||||||
///
|
///
|
||||||
/// # const IGNORE: &str = stringify! {
|
/// # const IGNORE: &str = stringify! {
|
||||||
/// fn demo1() -> Result<T> {...}
|
/// fn demo1() -> Result<T> {...}
|
||||||
/// // ^ equivalent to std::result::Result<T, anyhow::Error>
|
/// // ^ equivalent to std::result::Result<T, eyre::Error>
|
||||||
///
|
///
|
||||||
/// fn demo2() -> Result<T, OtherError> {...}
|
/// fn demo2() -> Result<T, OtherError> {...}
|
||||||
/// // ^ equivalent to std::result::Result<T, OtherError>
|
/// // ^ equivalent to std::result::Result<T, OtherError>
|
||||||
@ -387,7 +387,7 @@ pub struct Chain<'a> {
|
|||||||
/// #
|
/// #
|
||||||
/// # impl Deserialize for ClusterMap {}
|
/// # impl Deserialize for ClusterMap {}
|
||||||
/// #
|
/// #
|
||||||
/// use anyhow::Result;
|
/// use eyre::Result;
|
||||||
///
|
///
|
||||||
/// fn main() -> Result<()> {
|
/// fn main() -> Result<()> {
|
||||||
/// # return Ok(());
|
/// # return Ok(());
|
||||||
@ -397,19 +397,19 @@ pub struct Chain<'a> {
|
|||||||
/// Ok(())
|
/// Ok(())
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub type Result<T, E = Error> = core::result::Result<T, E>;
|
pub type Result<T, E = ErrReport> = core::result::Result<T, E>;
|
||||||
|
|
||||||
/// Provides the `context` method for `Result`.
|
/// Provides the `context` method for `Result`.
|
||||||
///
|
///
|
||||||
/// This trait is sealed and cannot be implemented for types outside of
|
/// This trait is sealed and cannot be implemented for types outside of
|
||||||
/// `anyhow`.
|
/// `eyre`.
|
||||||
///
|
///
|
||||||
/// <br>
|
/// <br>
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use anyhow::{Context, Result};
|
/// use eyre::{Context, Result};
|
||||||
/// use std::fs;
|
/// use std::fs;
|
||||||
/// use std::path::PathBuf;
|
/// use std::path::PathBuf;
|
||||||
///
|
///
|
||||||
@ -452,7 +452,7 @@ pub type Result<T, E = Error> = core::result::Result<T, E>;
|
|||||||
/// # Effect on downcasting
|
/// # Effect on downcasting
|
||||||
///
|
///
|
||||||
/// After attaching context of type `C` onto an error of type `E`, the resulting
|
/// After attaching context of type `C` onto an error of type `E`, the resulting
|
||||||
/// `anyhow::Error` may be downcast to `C` **or** to `E`.
|
/// `eyre::Error` may be downcast to `C` **or** to `E`.
|
||||||
///
|
///
|
||||||
/// That is, in codebases that rely on downcasting, Anyhow's context supports
|
/// That is, in codebases that rely on downcasting, Anyhow's context supports
|
||||||
/// both of the following use cases:
|
/// both of the following use cases:
|
||||||
@ -468,7 +468,7 @@ pub type Result<T, E = Error> = core::result::Result<T, E>;
|
|||||||
/// be helpful.
|
/// be helpful.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # use anyhow::bail;
|
/// # use eyre::bail;
|
||||||
/// # use thiserror::Error;
|
/// # use thiserror::Error;
|
||||||
/// #
|
/// #
|
||||||
/// # #[derive(Error, Debug)]
|
/// # #[derive(Error, Debug)]
|
||||||
@ -479,7 +479,7 @@ pub type Result<T, E = Error> = core::result::Result<T, E>;
|
|||||||
/// # bail!(SuspiciousError);
|
/// # bail!(SuspiciousError);
|
||||||
/// # }
|
/// # }
|
||||||
/// #
|
/// #
|
||||||
/// use anyhow::{Context, Result};
|
/// use eyre::{Context, Result};
|
||||||
///
|
///
|
||||||
/// fn do_it() -> Result<()> {
|
/// fn do_it() -> Result<()> {
|
||||||
/// helper().context("Failed to complete the work")?;
|
/// helper().context("Failed to complete the work")?;
|
||||||
@ -508,7 +508,7 @@ pub type Result<T, E = Error> = core::result::Result<T, E>;
|
|||||||
/// the application.
|
/// the application.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # use anyhow::bail;
|
/// # use eyre::bail;
|
||||||
/// # use thiserror::Error;
|
/// # use thiserror::Error;
|
||||||
/// #
|
/// #
|
||||||
/// # #[derive(Error, Debug)]
|
/// # #[derive(Error, Debug)]
|
||||||
@ -519,7 +519,7 @@ pub type Result<T, E = Error> = core::result::Result<T, E>;
|
|||||||
/// # bail!("no such file or directory");
|
/// # bail!("no such file or directory");
|
||||||
/// # }
|
/// # }
|
||||||
/// #
|
/// #
|
||||||
/// use anyhow::{Context, Result};
|
/// use eyre::{Context, Result};
|
||||||
///
|
///
|
||||||
/// fn do_it() -> Result<()> {
|
/// fn do_it() -> Result<()> {
|
||||||
/// helper().context(HelperFailed)?;
|
/// helper().context(HelperFailed)?;
|
||||||
@ -542,13 +542,13 @@ pub type Result<T, E = Error> = core::result::Result<T, E>;
|
|||||||
/// ```
|
/// ```
|
||||||
pub trait Context<T, E>: context::private::Sealed {
|
pub trait Context<T, E>: context::private::Sealed {
|
||||||
/// Wrap the error value with additional context.
|
/// Wrap the error value with additional context.
|
||||||
fn context<C>(self, context: C) -> Result<T, Error>
|
fn context<C>(self, context: C) -> Result<T, ErrReport>
|
||||||
where
|
where
|
||||||
C: Display + Send + Sync + 'static;
|
C: Display + Send + Sync + 'static;
|
||||||
|
|
||||||
/// Wrap the error value with additional context that is evaluated lazily
|
/// Wrap the error value with additional context that is evaluated lazily
|
||||||
/// only once an error does occur.
|
/// only once an error does occur.
|
||||||
fn with_context<C, F>(self, f: F) -> Result<T, Error>
|
fn with_context<C, F>(self, f: F) -> Result<T, ErrReport>
|
||||||
where
|
where
|
||||||
C: Display + Send + Sync + 'static,
|
C: Display + Send + Sync + 'static,
|
||||||
F: FnOnce() -> C;
|
F: FnOnce() -> C;
|
||||||
@ -557,7 +557,7 @@ pub trait Context<T, E>: context::private::Sealed {
|
|||||||
// Not public API. Referenced by macro-generated code.
|
// Not public API. Referenced by macro-generated code.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub mod private {
|
pub mod private {
|
||||||
use crate::Error;
|
use crate::ErrReport;
|
||||||
use core::fmt::{Debug, Display};
|
use core::fmt::{Debug, Display};
|
||||||
|
|
||||||
#[cfg(backtrace)]
|
#[cfg(backtrace)]
|
||||||
@ -573,10 +573,10 @@ pub mod private {
|
|||||||
pub use crate::kind::BoxedKind;
|
pub use crate::kind::BoxedKind;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_adhoc<M>(message: M) -> Error
|
pub fn new_adhoc<M>(message: M) -> ErrReport
|
||||||
where
|
where
|
||||||
M: Display + Debug + Send + Sync + 'static,
|
M: Display + Debug + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
Error::from_adhoc(message, backtrace!())
|
ErrReport::from_adhoc(message, backtrace!())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # use anyhow::{bail, Result};
|
/// # use eyre::{bail, Result};
|
||||||
/// #
|
/// #
|
||||||
/// # fn has_permission(user: usize, resource: usize) -> bool {
|
/// # fn has_permission(user: usize, resource: usize) -> bool {
|
||||||
/// # true
|
/// # true
|
||||||
@ -23,7 +23,7 @@
|
|||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # use anyhow::{bail, Result};
|
/// # use eyre::{bail, Result};
|
||||||
/// # use thiserror::Error;
|
/// # use thiserror::Error;
|
||||||
/// #
|
/// #
|
||||||
/// # const MAX_DEPTH: usize = 1;
|
/// # const MAX_DEPTH: usize = 1;
|
||||||
@ -50,13 +50,13 @@
|
|||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! bail {
|
macro_rules! bail {
|
||||||
($msg:literal $(,)?) => {
|
($msg:literal $(,)?) => {
|
||||||
return $crate::private::Err($crate::anyhow!($msg));
|
return $crate::private::Err($crate::eyre!($msg));
|
||||||
};
|
};
|
||||||
($err:expr $(,)?) => {
|
($err:expr $(,)?) => {
|
||||||
return $crate::private::Err($crate::anyhow!($err));
|
return $crate::private::Err($crate::eyre!($err));
|
||||||
};
|
};
|
||||||
($fmt:expr, $($arg:tt)*) => {
|
($fmt:expr, $($arg:tt)*) => {
|
||||||
return $crate::private::Err($crate::anyhow!($fmt, $($arg)*));
|
return $crate::private::Err($crate::eyre!($fmt, $($arg)*));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ macro_rules! bail {
|
|||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # use anyhow::{ensure, Result};
|
/// # use eyre::{ensure, Result};
|
||||||
/// #
|
/// #
|
||||||
/// # fn main() -> Result<()> {
|
/// # fn main() -> Result<()> {
|
||||||
/// # let user = 0;
|
/// # let user = 0;
|
||||||
@ -82,7 +82,7 @@ macro_rules! bail {
|
|||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # use anyhow::{ensure, Result};
|
/// # use eyre::{ensure, Result};
|
||||||
/// # use thiserror::Error;
|
/// # use thiserror::Error;
|
||||||
/// #
|
/// #
|
||||||
/// # const MAX_DEPTH: usize = 1;
|
/// # const MAX_DEPTH: usize = 1;
|
||||||
@ -108,17 +108,17 @@ macro_rules! bail {
|
|||||||
macro_rules! ensure {
|
macro_rules! ensure {
|
||||||
($cond:expr, $msg:literal $(,)?) => {
|
($cond:expr, $msg:literal $(,)?) => {
|
||||||
if !$cond {
|
if !$cond {
|
||||||
return $crate::private::Err($crate::anyhow!($msg));
|
return $crate::private::Err($crate::eyre!($msg));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
($cond:expr, $err:expr $(,)?) => {
|
($cond:expr, $err:expr $(,)?) => {
|
||||||
if !$cond {
|
if !$cond {
|
||||||
return $crate::private::Err($crate::anyhow!($err));
|
return $crate::private::Err($crate::eyre!($err));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
($cond:expr, $fmt:expr, $($arg:tt)*) => {
|
($cond:expr, $fmt:expr, $($arg:tt)*) => {
|
||||||
if !$cond {
|
if !$cond {
|
||||||
return $crate::private::Err($crate::anyhow!($fmt, $($arg)*));
|
return $crate::private::Err($crate::eyre!($fmt, $($arg)*));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -134,11 +134,11 @@ macro_rules! ensure {
|
|||||||
/// ```
|
/// ```
|
||||||
/// # type V = ();
|
/// # type V = ();
|
||||||
/// #
|
/// #
|
||||||
/// use anyhow::{anyhow, Result};
|
/// use eyre::{eyre, Result};
|
||||||
///
|
///
|
||||||
/// fn lookup(key: &str) -> Result<V> {
|
/// fn lookup(key: &str) -> Result<V> {
|
||||||
/// if key.len() != 16 {
|
/// if key.len() != 16 {
|
||||||
/// return Err(anyhow!("key length must be 16 characters, got {:?}", key));
|
/// return Err(eyre!("key length must be 16 characters, got {:?}", key));
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// // ...
|
/// // ...
|
||||||
@ -146,7 +146,7 @@ macro_rules! ensure {
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! anyhow {
|
macro_rules! eyre {
|
||||||
($msg:literal $(,)?) => {
|
($msg:literal $(,)?) => {
|
||||||
// Handle $:literal as a special case to make cargo-expanded code more
|
// Handle $:literal as a special case to make cargo-expanded code more
|
||||||
// concise in the common case.
|
// concise in the common case.
|
||||||
@ -155,7 +155,7 @@ macro_rules! anyhow {
|
|||||||
($err:expr $(,)?) => ({
|
($err:expr $(,)?) => ({
|
||||||
use $crate::private::kind::*;
|
use $crate::private::kind::*;
|
||||||
let error = $err;
|
let error = $err;
|
||||||
(&error).anyhow_kind().new(error)
|
(&error).eyre_kind().new(error)
|
||||||
});
|
});
|
||||||
($fmt:expr, $($arg:tt)*) => {
|
($fmt:expr, $($arg:tt)*) => {
|
||||||
$crate::private::new_adhoc(format!($fmt, $($arg)*))
|
$crate::private::new_adhoc(format!($fmt, $($arg)*))
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use anyhow::{bail, Result};
|
use eyre::{bail, Result};
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
pub fn bail_literal() -> Result<()> {
|
pub fn bail_literal() -> Result<()> {
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
use anyhow::Error;
|
use eyre::ErrReport;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_send() {
|
fn test_send() {
|
||||||
fn assert_send<T: Send>() {}
|
fn assert_send<T: Send>() {}
|
||||||
assert_send::<Error>();
|
assert_send::<ErrReport>();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_sync() {
|
fn test_sync() {
|
||||||
fn assert_sync<T: Sync>() {}
|
fn assert_sync<T: Sync>() {}
|
||||||
assert_sync::<Error>();
|
assert_sync::<ErrReport>();
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,8 @@ fn test_backtrace() {}
|
|||||||
#[rustversion::nightly]
|
#[rustversion::nightly]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_backtrace() {
|
fn test_backtrace() {
|
||||||
use anyhow::anyhow;
|
use eyre::eyre;
|
||||||
|
|
||||||
let error = anyhow!("oh no!");
|
let error = eyre!("oh no!");
|
||||||
let _ = error.backtrace();
|
let _ = error.backtrace();
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use anyhow::anyhow;
|
use eyre::eyre;
|
||||||
use std::error::Error as StdError;
|
use std::error::Error as StdError;
|
||||||
use std::io;
|
use std::io;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
@ -12,7 +12,7 @@ struct MyError {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_boxed_str() {
|
fn test_boxed_str() {
|
||||||
let error = Box::<dyn StdError + Send + Sync>::from("oh no!");
|
let error = Box::<dyn StdError + Send + Sync>::from("oh no!");
|
||||||
let error = anyhow!(error);
|
let error = eyre!(error);
|
||||||
assert_eq!("oh no!", error.to_string());
|
assert_eq!("oh no!", error.to_string());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
"oh no!",
|
"oh no!",
|
||||||
@ -28,13 +28,13 @@ fn test_boxed_thiserror() {
|
|||||||
let error = MyError {
|
let error = MyError {
|
||||||
source: io::Error::new(io::ErrorKind::Other, "oh no!"),
|
source: io::Error::new(io::ErrorKind::Other, "oh no!"),
|
||||||
};
|
};
|
||||||
let error = anyhow!(error);
|
let error = eyre!(error);
|
||||||
assert_eq!("oh no!", error.source().unwrap().to_string());
|
assert_eq!("oh no!", error.source().unwrap().to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_boxed_anyhow() {
|
fn test_boxed_eyre() {
|
||||||
let error = anyhow!("oh no!").context("it failed");
|
let error = eyre!("oh no!").context("it failed");
|
||||||
let error = anyhow!(error);
|
let error = eyre!(error);
|
||||||
assert_eq!("oh no!", error.source().unwrap().to_string());
|
assert_eq!("oh no!", error.source().unwrap().to_string());
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use anyhow::{anyhow, Error};
|
use eyre::{eyre, ErrReport};
|
||||||
|
|
||||||
fn error() -> Error {
|
fn error() -> ErrReport {
|
||||||
anyhow!(0).context(1).context(2).context(3)
|
eyre!(0).context(1).context(2).context(3)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
mod drop;
|
mod drop;
|
||||||
|
|
||||||
use crate::drop::{DetectDrop, Flag};
|
use crate::drop::{DetectDrop, Flag};
|
||||||
use anyhow::{Context, Error, Result};
|
use eyre::{Context, ErrReport, Result};
|
||||||
use std::fmt::{self, Display};
|
use std::fmt::{self, Display};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
// https://github.com/dtolnay/anyhow/issues/18
|
// https://github.com/dtolnay/eyre/issues/18
|
||||||
#[test]
|
#[test]
|
||||||
fn test_inference() -> Result<()> {
|
fn test_inference() -> Result<()> {
|
||||||
let x = "1";
|
let x = "1";
|
||||||
@ -56,7 +56,7 @@ impl Dropped {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_chain() -> (Error, Dropped) {
|
fn make_chain() -> (ErrReport, Dropped) {
|
||||||
let dropped = Dropped {
|
let dropped = Dropped {
|
||||||
low: Flag::new(),
|
low: Flag::new(),
|
||||||
mid: Flag::new(),
|
mid: Flag::new(),
|
||||||
@ -77,7 +77,7 @@ fn make_chain() -> (Error, Dropped) {
|
|||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
|
|
||||||
// impl Context for Result<T, Error>
|
// impl Context for Result<T, Error>
|
||||||
let high = Err::<(), Error>(mid)
|
let high = Err::<(), ErrReport>(mid)
|
||||||
.context(HighLevel {
|
.context(HighLevel {
|
||||||
message: "failed to start server",
|
message: "failed to start server",
|
||||||
drop: DetectDrop::new(&dropped.high),
|
drop: DetectDrop::new(&dropped.high),
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
mod drop;
|
mod drop;
|
||||||
|
|
||||||
use self::drop::{DetectDrop, Flag};
|
use self::drop::{DetectDrop, Flag};
|
||||||
use anyhow::{Error, Result};
|
use eyre::{ErrReport, Result};
|
||||||
use std::error::Error as StdError;
|
use std::error::Error as StdError;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_convert() {
|
fn test_convert() {
|
||||||
let has_dropped = Flag::new();
|
let has_dropped = Flag::new();
|
||||||
let error = Error::new(DetectDrop::new(&has_dropped));
|
let error = ErrReport::new(DetectDrop::new(&has_dropped));
|
||||||
let box_dyn = Box::<dyn StdError + Send + Sync>::from(error);
|
let box_dyn = Box::<dyn StdError + Send + Sync>::from(error);
|
||||||
assert_eq!("oh no!", box_dyn.to_string());
|
assert_eq!("oh no!", box_dyn.to_string());
|
||||||
drop(box_dyn);
|
drop(box_dyn);
|
||||||
|
@ -3,7 +3,7 @@ mod drop;
|
|||||||
|
|
||||||
use self::common::*;
|
use self::common::*;
|
||||||
use self::drop::{DetectDrop, Flag};
|
use self::drop::{DetectDrop, Flag};
|
||||||
use anyhow::Error;
|
use eyre::ErrReport;
|
||||||
use std::error::Error as StdError;
|
use std::error::Error as StdError;
|
||||||
use std::fmt::{self, Display};
|
use std::fmt::{self, Display};
|
||||||
use std::io;
|
use std::io;
|
||||||
@ -71,7 +71,7 @@ fn test_downcast_mut() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_drop() {
|
fn test_drop() {
|
||||||
let has_dropped = Flag::new();
|
let has_dropped = Flag::new();
|
||||||
let error = Error::new(DetectDrop::new(&has_dropped));
|
let error = ErrReport::new(DetectDrop::new(&has_dropped));
|
||||||
drop(error.downcast::<DetectDrop>().unwrap());
|
drop(error.downcast::<DetectDrop>().unwrap());
|
||||||
assert!(has_dropped.get());
|
assert!(has_dropped.get());
|
||||||
}
|
}
|
||||||
@ -90,7 +90,7 @@ fn test_large_alignment() {
|
|||||||
|
|
||||||
impl StdError for LargeAlignedError {}
|
impl StdError for LargeAlignedError {}
|
||||||
|
|
||||||
let error = Error::new(LargeAlignedError("oh no!"));
|
let error = ErrReport::new(LargeAlignedError("oh no!"));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
"oh no!",
|
"oh no!",
|
||||||
error.downcast_ref::<LargeAlignedError>().unwrap().0
|
error.downcast_ref::<LargeAlignedError>().unwrap().0
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use anyhow::{bail, Context, Result};
|
use eyre::{bail, Context, Result};
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
fn f() -> Result<()> {
|
fn f() -> Result<()> {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
mod common;
|
mod common;
|
||||||
|
|
||||||
use self::common::*;
|
use self::common::*;
|
||||||
use anyhow::ensure;
|
use eyre::ensure;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_messages() {
|
fn test_messages() {
|
||||||
|
@ -1,29 +1,29 @@
|
|||||||
mod drop;
|
mod drop;
|
||||||
|
|
||||||
use self::drop::{DetectDrop, Flag};
|
use self::drop::{DetectDrop, Flag};
|
||||||
use anyhow::Error;
|
use eyre::ErrReport;
|
||||||
use std::marker::Unpin;
|
use std::marker::Unpin;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_error_size() {
|
fn test_error_size() {
|
||||||
assert_eq!(mem::size_of::<Error>(), mem::size_of::<usize>());
|
assert_eq!(mem::size_of::<ErrReport>(), mem::size_of::<usize>());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_null_pointer_optimization() {
|
fn test_null_pointer_optimization() {
|
||||||
assert_eq!(mem::size_of::<Result<(), Error>>(), mem::size_of::<usize>());
|
assert_eq!(mem::size_of::<Result<(), ErrReport>>(), mem::size_of::<usize>());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_autotraits() {
|
fn test_autotraits() {
|
||||||
fn assert<E: Unpin + Send + Sync + 'static>() {}
|
fn assert<E: Unpin + Send + Sync + 'static>() {}
|
||||||
assert::<Error>();
|
assert::<ErrReport>();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_drop() {
|
fn test_drop() {
|
||||||
let has_dropped = Flag::new();
|
let has_dropped = Flag::new();
|
||||||
drop(Error::new(DetectDrop::new(&has_dropped)));
|
drop(ErrReport::new(DetectDrop::new(&has_dropped)));
|
||||||
assert!(has_dropped.get());
|
assert!(has_dropped.get());
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use anyhow::anyhow;
|
use eyre::eyre;
|
||||||
use std::error::Error as StdError;
|
use std::error::Error as StdError;
|
||||||
use std::fmt::{self, Display};
|
use std::fmt::{self, Display};
|
||||||
use std::io;
|
use std::io;
|
||||||
@ -26,37 +26,37 @@ impl StdError for TestError {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_literal_source() {
|
fn test_literal_source() {
|
||||||
let error = anyhow!("oh no!");
|
let error = eyre!("oh no!");
|
||||||
assert!(error.source().is_none());
|
assert!(error.source().is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_variable_source() {
|
fn test_variable_source() {
|
||||||
let msg = "oh no!";
|
let msg = "oh no!";
|
||||||
let error = anyhow!(msg);
|
let error = eyre!(msg);
|
||||||
assert!(error.source().is_none());
|
assert!(error.source().is_none());
|
||||||
|
|
||||||
let msg = msg.to_owned();
|
let msg = msg.to_owned();
|
||||||
let error = anyhow!(msg);
|
let error = eyre!(msg);
|
||||||
assert!(error.source().is_none());
|
assert!(error.source().is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fmt_source() {
|
fn test_fmt_source() {
|
||||||
let error = anyhow!("{} {}!", "oh", "no");
|
let error = eyre!("{} {}!", "oh", "no");
|
||||||
assert!(error.source().is_none());
|
assert!(error.source().is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_io_source() {
|
fn test_io_source() {
|
||||||
let io = io::Error::new(io::ErrorKind::Other, "oh no!");
|
let io = io::Error::new(io::ErrorKind::Other, "oh no!");
|
||||||
let error = anyhow!(TestError::Io(io));
|
let error = eyre!(TestError::Io(io));
|
||||||
assert_eq!("oh no!", error.source().unwrap().to_string());
|
assert_eq!("oh no!", error.source().unwrap().to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_anyhow_from_anyhow() {
|
fn test_eyre_from_eyre() {
|
||||||
let error = anyhow!("oh no!").context("context");
|
let error = eyre!("oh no!").context("context");
|
||||||
let error = anyhow!(error);
|
let error = eyre!(error);
|
||||||
assert_eq!("oh no!", error.source().unwrap().to_string());
|
assert_eq!("oh no!", error.source().unwrap().to_string());
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use anyhow::anyhow;
|
use eyre::eyre;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Error;
|
struct Error;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let _ = anyhow!(Error);
|
let _ = eyre!(Error);
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
error[E0599]: no method named `anyhow_kind` found for reference `&Error` in the current scope
|
error[E0599]: no method named `eyre_kind` found for reference `&Error` in the current scope
|
||||||
--> $DIR/no-impl.rs:7:13
|
--> $DIR/no-impl.rs:7:13
|
||||||
|
|
|
|
||||||
7 | let _ = anyhow!(Error);
|
7 | let _ = eyre!(Error);
|
||||||
| ^^^^^^^^^^^^^^ method not found in `&Error`
|
| ^^^^^^^^^^^^ method not found in `&Error`
|
||||||
|
|
|
|
||||||
= note: the method `anyhow_kind` exists but the following trait bounds were not satisfied:
|
= note: the method `eyre_kind` exists but the following trait bounds were not satisfied:
|
||||||
`&Error : anyhow::kind::AdhocKind`
|
`&Error : eyre::kind::AdhocKind`
|
||||||
`&Error : anyhow::kind::TraitKind`
|
`&Error : eyre::kind::TraitKind`
|
||||||
`Error : anyhow::kind::TraitKind`
|
`Error : eyre::kind::TraitKind`
|
||||||
= help: items from traits can only be used if the trait is implemented and in scope
|
= help: items from traits can only be used if the trait is implemented and in scope
|
||||||
= note: the following traits define an item `anyhow_kind`, perhaps you need to implement one of them:
|
= note: the following traits define an item `eyre_kind`, perhaps you need to implement one of them:
|
||||||
candidate #1: `anyhow::kind::AdhocKind`
|
candidate #1: `eyre::kind::AdhocKind`
|
||||||
candidate #2: `anyhow::kind::TraitKind`
|
candidate #2: `eyre::kind::TraitKind`
|
||||||
candidate #3: `anyhow::kind::BoxedKind`
|
candidate #3: `eyre::kind::BoxedKind`
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user