mirror of
https://github.com/eyre-rs/eyre.git
synced 2025-09-28 21:41:58 +00:00
Rename core types
This commit is contained in:
parent
bac602c301
commit
86da223cde
@ -1,17 +1,17 @@
|
||||
[package]
|
||||
name = "anyhow"
|
||||
name = "eyre"
|
||||
version = "1.0.26" # remember to update html_root_url
|
||||
authors = ["David Tolnay <dtolnay@gmail.com>"]
|
||||
edition = "2018"
|
||||
license = "MIT OR Apache-2.0"
|
||||
description = "Flexible concrete Error type built on std::error::Error"
|
||||
repository = "https://github.com/dtolnay/anyhow"
|
||||
documentation = "https://docs.rs/anyhow"
|
||||
repository = "https://github.com/dtolnay/eyre"
|
||||
documentation = "https://docs.rs/eyre"
|
||||
readme = "README.md"
|
||||
categories = ["rust-patterns"]
|
||||
|
||||
[badges]
|
||||
travis-ci = { repository = "dtolnay/anyhow" }
|
||||
travis-ci = { repository = "dtolnay/eyre" }
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
|
28
README.md
28
README.md
@ -1,18 +1,18 @@
|
||||
Anyhow ¯\\\_(ツ)\_/¯
|
||||
=========================
|
||||
|
||||
[](https://travis-ci.com/dtolnay/anyhow)
|
||||
[](https://crates.io/crates/anyhow)
|
||||
[](https://docs.rs/anyhow)
|
||||
[](https://travis-ci.com/dtolnay/eyre)
|
||||
[](https://crates.io/crates/eyre)
|
||||
[](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.
|
||||
|
||||
[Error]: https://docs.rs/anyhow/1.0/anyhow/struct.Error.html
|
||||
[Error]: https://docs.rs/eyre/1.0/eyre/struct.Error.html
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
eyre = "1.0"
|
||||
```
|
||||
|
||||
*Compiler support: requires rustc 1.34+*
|
||||
@ -21,14 +21,14 @@ anyhow = "1.0"
|
||||
|
||||
## 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.
|
||||
|
||||
Within the function, use `?` to easily propagate any error that implements the
|
||||
`std::error::Error` trait.
|
||||
|
||||
```rust
|
||||
use anyhow::Result;
|
||||
use eyre::Result;
|
||||
|
||||
fn get_cluster_info() -> Result<ClusterMap> {
|
||||
let config = std::fs::read_to_string("cluster.json")?;
|
||||
@ -43,7 +43,7 @@ anyhow = "1.0"
|
||||
application was in the middle of.
|
||||
|
||||
```rust
|
||||
use anyhow::{Context, Result};
|
||||
use eyre::{Context, Result};
|
||||
|
||||
fn main() -> Result<()> {
|
||||
...
|
||||
@ -98,11 +98,11 @@ anyhow = "1.0"
|
||||
}
|
||||
```
|
||||
|
||||
- One-off error messages can be constructed using the `anyhow!` macro, which
|
||||
supports string interpolation and produces an `anyhow::Error`.
|
||||
- One-off error messages can be constructed using the `eyre!` macro, which
|
||||
supports string interpolation and produces an `eyre::Error`.
|
||||
|
||||
```rust
|
||||
return Err(anyhow!("Missing attribute: {}", missing));
|
||||
return Err(eyre!("Missing attribute: {}", missing));
|
||||
```
|
||||
|
||||
<br>
|
||||
@ -115,7 +115,7 @@ Cargo.toml. A global allocator is required.
|
||||
|
||||
```toml
|
||||
[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
|
||||
@ -127,7 +127,7 @@ type inside a function that returns Anyhow's error type.
|
||||
|
||||
## 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
|
||||
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].
|
||||
|
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
|
||||
// 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#"
|
||||
#![feature(backtrace)]
|
||||
#![allow(dead_code)]
|
||||
@ -51,7 +51,7 @@ fn compile_probe() -> Option<ExitStatus> {
|
||||
fs::write(&probefile, PROBE).ok()?;
|
||||
Command::new(rustc)
|
||||
.arg("--edition=2018")
|
||||
.arg("--crate-name=anyhow_build")
|
||||
.arg("--crate-name=eyre_build")
|
||||
.arg("--crate-type=lib")
|
||||
.arg("--emit=metadata")
|
||||
.arg("--out-dir")
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::error::ContextError;
|
||||
use crate::{Context, Error, StdError};
|
||||
use crate::{Context, ErrReport, StdError};
|
||||
use core::convert::Infallible;
|
||||
use core::fmt::{self, Debug, Display, Write};
|
||||
|
||||
@ -10,7 +10,7 @@ mod ext {
|
||||
use super::*;
|
||||
|
||||
pub trait StdError {
|
||||
fn ext_context<C>(self, context: C) -> Error
|
||||
fn ext_context<C>(self, context: C) -> ErrReport
|
||||
where
|
||||
C: Display + Send + Sync + 'static;
|
||||
}
|
||||
@ -20,17 +20,17 @@ mod ext {
|
||||
where
|
||||
E: std::error::Error + Send + Sync + 'static,
|
||||
{
|
||||
fn ext_context<C>(self, context: C) -> Error
|
||||
fn ext_context<C>(self, context: C) -> ErrReport
|
||||
where
|
||||
C: Display + Send + Sync + 'static,
|
||||
{
|
||||
let backtrace = backtrace_if_absent!(self);
|
||||
Error::from_context(context, self, backtrace)
|
||||
ErrReport::from_context(context, self, backtrace)
|
||||
}
|
||||
}
|
||||
|
||||
impl StdError for Error {
|
||||
fn ext_context<C>(self, context: C) -> Error
|
||||
impl StdError for ErrReport {
|
||||
fn ext_context<C>(self, context: C) -> ErrReport
|
||||
where
|
||||
C: Display + Send + Sync + 'static,
|
||||
{
|
||||
@ -43,14 +43,14 @@ impl<T, E> Context<T, E> for Result<T, E>
|
||||
where
|
||||
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
|
||||
C: Display + Send + Sync + 'static,
|
||||
{
|
||||
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
|
||||
C: Display + Send + Sync + 'static,
|
||||
F: FnOnce() -> C,
|
||||
@ -62,7 +62,7 @@ where
|
||||
/// ```
|
||||
/// # type T = ();
|
||||
/// #
|
||||
/// use anyhow::{Context, Result};
|
||||
/// use eyre::{Context, Result};
|
||||
///
|
||||
/// fn maybe_get() -> Option<T> {
|
||||
/// # const IGNORE: &str = stringify! {
|
||||
@ -80,19 +80,19 @@ where
|
||||
/// }
|
||||
/// ```
|
||||
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
|
||||
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
|
||||
C: Display + Send + Sync + 'static,
|
||||
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
|
||||
C: Display,
|
||||
{
|
||||
|
108
src/error.rs
108
src/error.rs
@ -1,7 +1,7 @@
|
||||
use crate::alloc::Box;
|
||||
use crate::backtrace::Backtrace;
|
||||
use crate::chain::Chain;
|
||||
use crate::{Error, StdError};
|
||||
use crate::{ErrReport, StdError};
|
||||
use core::any::TypeId;
|
||||
use core::fmt::{self, Debug, Display};
|
||||
use core::mem::{self, ManuallyDrop};
|
||||
@ -10,10 +10,10 @@ use core::ptr::{self, NonNull};
|
||||
#[cfg(feature = "std")]
|
||||
use core::ops::{Deref, DerefMut};
|
||||
|
||||
impl Error {
|
||||
impl ErrReport {
|
||||
/// 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.
|
||||
///
|
||||
/// If the error type does not provide a backtrace, a backtrace will be
|
||||
@ -24,18 +24,18 @@ impl Error {
|
||||
E: StdError + Send + Sync + 'static,
|
||||
{
|
||||
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.
|
||||
///
|
||||
/// 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
|
||||
/// 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.
|
||||
///
|
||||
/// `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
|
||||
/// as iterator or stream combinators:
|
||||
///
|
||||
@ -50,7 +50,7 @@ impl Error {
|
||||
/// #
|
||||
/// # use ffi::{Input, Output};
|
||||
/// #
|
||||
/// use anyhow::{Error, Result};
|
||||
/// use eyre::{ErrReport, Result};
|
||||
/// use futures::stream::{Stream, StreamExt, TryStreamExt};
|
||||
///
|
||||
/// async fn demo<S>(stream: S) -> Result<Vec<Output>>
|
||||
@ -59,7 +59,7 @@ impl Error {
|
||||
/// {
|
||||
/// stream
|
||||
/// .then(ffi::do_some_work) // returns Result<Output, &str>
|
||||
/// .map_err(Error::msg)
|
||||
/// .map_err(ErrReport::msg)
|
||||
/// .try_collect()
|
||||
/// .await
|
||||
/// }
|
||||
@ -68,7 +68,7 @@ impl Error {
|
||||
where
|
||||
M: Display + Debug + Send + Sync + 'static,
|
||||
{
|
||||
Error::from_adhoc(message, backtrace!())
|
||||
ErrReport::from_adhoc(message, backtrace!())
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
@ -87,7 +87,7 @@ impl Error {
|
||||
};
|
||||
|
||||
// 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
|
||||
@ -108,7 +108,7 @@ impl Error {
|
||||
|
||||
// Safety: MessageError is repr(transparent) so it is okay for the
|
||||
// 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
|
||||
@ -129,7 +129,7 @@ impl Error {
|
||||
|
||||
// Safety: DisplayError is repr(transparent) so it is okay for the
|
||||
// vtable to allow casting the DisplayError<M> to M.
|
||||
unsafe { Error::construct(error, vtable, backtrace) }
|
||||
unsafe { ErrReport::construct(error, vtable, backtrace) }
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
@ -151,7 +151,7 @@ impl Error {
|
||||
};
|
||||
|
||||
// Safety: passing vtable that operates on the right type.
|
||||
unsafe { Error::construct(error, vtable, backtrace) }
|
||||
unsafe { ErrReport::construct(error, vtable, backtrace) }
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
@ -173,7 +173,7 @@ impl Error {
|
||||
|
||||
// Safety: BoxedError is repr(transparent) so it is okay for the vtable
|
||||
// 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
|
||||
@ -202,7 +202,7 @@ impl Error {
|
||||
// caller rather than a builtin fat pointer vtable.
|
||||
let erased = mem::transmute::<Box<ErrorImpl<E>>, Box<ErrorImpl<()>>>(inner);
|
||||
let inner = ManuallyDrop::new(erased);
|
||||
Error { inner }
|
||||
ErrReport { inner }
|
||||
}
|
||||
|
||||
/// 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::path::Path;
|
||||
///
|
||||
@ -255,7 +255,7 @@ impl Error {
|
||||
/// "only the first {} lines of {} are valid",
|
||||
/// 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
|
||||
C: Display + Send + Sync + 'static,
|
||||
{
|
||||
let error: ContextError<C, Error> = ContextError {
|
||||
let error: ContextError<C, ErrReport> = ContextError {
|
||||
context,
|
||||
error: self,
|
||||
};
|
||||
|
||||
let vtable = &ErrorVTable {
|
||||
object_drop: object_drop::<ContextError<C, Error>>,
|
||||
object_ref: object_ref::<ContextError<C, Error>>,
|
||||
object_drop: object_drop::<ContextError<C, ErrReport>>,
|
||||
object_ref: object_ref::<ContextError<C, ErrReport>>,
|
||||
#[cfg(feature = "std")]
|
||||
object_mut: object_mut::<ContextError<C, Error>>,
|
||||
object_boxed: object_boxed::<ContextError<C, Error>>,
|
||||
object_mut: object_mut::<ContextError<C, ErrReport>>,
|
||||
object_boxed: object_boxed::<ContextError<C, ErrReport>>,
|
||||
object_downcast: context_chain_downcast::<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;
|
||||
|
||||
// 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:
|
||||
/// [rust-lang/rust#53487][tracking].
|
||||
@ -301,7 +301,7 @@ impl Error {
|
||||
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
|
||||
/// object, beginning with the error that this error object was created
|
||||
@ -310,10 +310,10 @@ impl Error {
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use anyhow::Error;
|
||||
/// use eyre::ErrReport;
|
||||
/// 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() {
|
||||
/// if let Some(io_error) = cause.downcast_ref::<io::Error>() {
|
||||
/// return Some(io_error.kind());
|
||||
@ -331,7 +331,7 @@ impl Error {
|
||||
/// cause's cause etc.
|
||||
///
|
||||
/// The root cause is the last error in the iterator produced by
|
||||
/// [`chain()`][Error::chain].
|
||||
/// [`chain()`][ErrReport::chain].
|
||||
#[cfg(feature = "std")]
|
||||
pub fn root_cause(&self) -> &(dyn StdError + 'static) {
|
||||
let mut chain = self.chain();
|
||||
@ -379,7 +379,7 @@ impl Error {
|
||||
let error = ptr::read(addr.cast::<E>().as_ptr());
|
||||
|
||||
// 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 erased = ManuallyDrop::into_inner(inner);
|
||||
|
||||
@ -395,7 +395,7 @@ impl Error {
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use anyhow::anyhow;
|
||||
/// # use eyre::eyre;
|
||||
/// # use std::fmt::{self, Display};
|
||||
/// # use std::task::Poll;
|
||||
/// #
|
||||
@ -414,7 +414,7 @@ impl Error {
|
||||
/// #
|
||||
/// # const REDACTED_CONTENT: () = ();
|
||||
/// #
|
||||
/// # let error = anyhow!("...");
|
||||
/// # let error = eyre!("...");
|
||||
/// # let root_cause = &error;
|
||||
/// #
|
||||
/// # let ret =
|
||||
@ -455,18 +455,18 @@ impl Error {
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<E> From<E> for Error
|
||||
impl<E> From<E> for ErrReport
|
||||
where
|
||||
E: StdError + Send + Sync + 'static,
|
||||
{
|
||||
fn from(error: E) -> Self {
|
||||
let backtrace = backtrace_if_absent!(error);
|
||||
Error::from_std(error, backtrace)
|
||||
ErrReport::from_std(error, backtrace)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl Deref for Error {
|
||||
impl Deref for ErrReport {
|
||||
type Target = dyn StdError + Send + Sync + 'static;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
@ -475,25 +475,25 @@ impl Deref for Error {
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl DerefMut for Error {
|
||||
impl DerefMut for ErrReport {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
self.inner.error_mut()
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Error {
|
||||
impl Display for ErrReport {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.inner.display(formatter)
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for Error {
|
||||
impl Debug for ErrReport {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.inner.debug(formatter)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Error {
|
||||
impl Drop for ErrReport {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
// 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<()>>
|
||||
where
|
||||
C: 'static,
|
||||
{
|
||||
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 ();
|
||||
Some(NonNull::new_unchecked(addr))
|
||||
} else {
|
||||
// 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;
|
||||
(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)
|
||||
where
|
||||
C: 'static,
|
||||
@ -649,14 +649,14 @@ where
|
||||
if TypeId::of::<C>() == target {
|
||||
let unerased = mem::transmute::<
|
||||
Box<ErrorImpl<()>>,
|
||||
Box<ErrorImpl<ContextError<ManuallyDrop<C>, Error>>>,
|
||||
Box<ErrorImpl<ContextError<ManuallyDrop<C>, ErrReport>>>,
|
||||
>(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);
|
||||
} else {
|
||||
let unerased = mem::transmute::<
|
||||
Box<ErrorImpl<()>>,
|
||||
Box<ErrorImpl<ContextError<C, ManuallyDrop<Error>>>>,
|
||||
Box<ErrorImpl<ContextError<C, ManuallyDrop<ErrReport>>>>,
|
||||
>(e);
|
||||
// Read out a ManuallyDrop<Box<ErrorImpl<()>>> from the next error.
|
||||
let inner = ptr::read(&unerased._object.error.inner);
|
||||
@ -756,12 +756,12 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Error> for Box<dyn StdError + Send + Sync + 'static> {
|
||||
fn from(error: Error) -> Self {
|
||||
impl From<ErrReport> for Box<dyn StdError + Send + Sync + 'static> {
|
||||
fn from(error: ErrReport) -> Self {
|
||||
let outer = ManuallyDrop::new(error);
|
||||
unsafe {
|
||||
// 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 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> {
|
||||
fn from(error: Error) -> Self {
|
||||
impl From<ErrReport> for Box<dyn StdError + 'static> {
|
||||
fn from(error: ErrReport) -> Self {
|
||||
Box::<dyn StdError + Send + Sync>::from(error)
|
||||
}
|
||||
}
|
||||
|
||||
#[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) {
|
||||
&**self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl AsRef<dyn StdError> for Error {
|
||||
impl AsRef<dyn StdError> for ErrReport {
|
||||
fn as_ref(&self) -> &(dyn StdError + 'static) {
|
||||
&**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
|
||||
// want the resulting Error to pick up the input's implementation of source()
|
||||
// When eyre! is given a single expr argument to turn into eyre::ErrReport, we
|
||||
// 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
|
||||
// more than Display and Debug.
|
||||
//
|
||||
// Expressed in terms of specialization, we want something like:
|
||||
//
|
||||
// trait AnyhowNew {
|
||||
// fn new(self) -> Error;
|
||||
// trait EyreNew {
|
||||
// fn new(self) -> ErrReport;
|
||||
// }
|
||||
//
|
||||
// impl<T> AnyhowNew for T
|
||||
// impl<T> EyreNew for T
|
||||
// where
|
||||
// T: Display + Debug + Send + Sync + 'static,
|
||||
// {
|
||||
// default fn new(self) -> Error {
|
||||
// default fn new(self) -> ErrReport {
|
||||
// /* no std error impl */
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// impl<T> AnyhowNew for T
|
||||
// impl<T> EyreNew for T
|
||||
// where
|
||||
// T: std::error::Error + Send + Sync + 'static,
|
||||
// {
|
||||
// fn new(self) -> Error {
|
||||
// fn new(self) -> ErrReport {
|
||||
// /* use std error's source() and backtrace() */
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Since specialization is not stable yet, instead we rely on autoref behavior
|
||||
// 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
|
||||
// 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
|
||||
// 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)]
|
||||
// use $crate::private::{AdhocKind, TraitKind};
|
||||
// let error = $msg;
|
||||
// (&error).anyhow_kind().new(error)
|
||||
// (&error).eyre_kind().new(error)
|
||||
|
||||
use crate::Error;
|
||||
use crate::ErrReport;
|
||||
use core::fmt::{Debug, Display};
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
@ -57,7 +57,7 @@ pub struct Adhoc;
|
||||
|
||||
pub trait AdhocKind: Sized {
|
||||
#[inline]
|
||||
fn anyhow_kind(&self) -> Adhoc {
|
||||
fn eyre_kind(&self) -> Adhoc {
|
||||
Adhoc
|
||||
}
|
||||
}
|
||||
@ -65,11 +65,11 @@ pub trait AdhocKind: Sized {
|
||||
impl<T> AdhocKind for &T where T: ?Sized + Display + Debug + Send + Sync + 'static {}
|
||||
|
||||
impl Adhoc {
|
||||
pub fn new<M>(self, message: M) -> Error
|
||||
pub fn new<M>(self, message: M) -> ErrReport
|
||||
where
|
||||
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 {
|
||||
#[inline]
|
||||
fn anyhow_kind(&self) -> Trait {
|
||||
fn eyre_kind(&self) -> Trait {
|
||||
Trait
|
||||
}
|
||||
}
|
||||
|
||||
impl<E> TraitKind for E where E: Into<Error> {}
|
||||
impl<E> TraitKind for E where E: Into<ErrReport> {}
|
||||
|
||||
impl Trait {
|
||||
pub fn new<E>(self, error: E) -> Error
|
||||
pub fn new<E>(self, error: E) -> ErrReport
|
||||
where
|
||||
E: Into<Error>,
|
||||
E: Into<ErrReport>,
|
||||
{
|
||||
error.into()
|
||||
}
|
||||
@ -99,7 +99,7 @@ pub struct Boxed;
|
||||
#[cfg(feature = "std")]
|
||||
pub trait BoxedKind: Sized {
|
||||
#[inline]
|
||||
fn anyhow_kind(&self) -> Boxed {
|
||||
fn eyre_kind(&self) -> Boxed {
|
||||
Boxed
|
||||
}
|
||||
}
|
||||
@ -109,8 +109,8 @@ impl BoxedKind for Box<dyn StdError + Send + Sync> {}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
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);
|
||||
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.
|
||||
//!
|
||||
//! <br>
|
||||
//!
|
||||
//! # 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.
|
||||
//!
|
||||
//! Within the function, use `?` to easily propagate any error that implements
|
||||
//! the `std::error::Error` trait.
|
||||
//! the `std::error::ErrReport` trait.
|
||||
//!
|
||||
//! ```
|
||||
//! # pub trait Deserialize {}
|
||||
@ -27,7 +27,7 @@
|
||||
//! #
|
||||
//! # impl Deserialize for ClusterMap {}
|
||||
//! #
|
||||
//! use anyhow::Result;
|
||||
//! use eyre::Result;
|
||||
//!
|
||||
//! fn get_cluster_info() -> Result<ClusterMap> {
|
||||
//! let config = std::fs::read_to_string("cluster.json")?;
|
||||
@ -52,7 +52,7 @@
|
||||
//! # }
|
||||
//! # }
|
||||
//! #
|
||||
//! use anyhow::{Context, Result};
|
||||
//! use eyre::{Context, Result};
|
||||
//!
|
||||
//! fn main() -> Result<()> {
|
||||
//! # return Ok(());
|
||||
@ -88,7 +88,7 @@
|
||||
//! mutable reference as needed.
|
||||
//!
|
||||
//! ```
|
||||
//! # use anyhow::anyhow;
|
||||
//! # use eyre::eyre;
|
||||
//! # use std::fmt::{self, Display};
|
||||
//! # use std::task::Poll;
|
||||
//! #
|
||||
@ -107,7 +107,7 @@
|
||||
//! #
|
||||
//! # const REDACTED_CONTENT: () = ();
|
||||
//! #
|
||||
//! # let error = anyhow!("...");
|
||||
//! # let error = eyre!("...");
|
||||
//! # let root_cause = &error;
|
||||
//! #
|
||||
//! # let ret =
|
||||
@ -146,15 +146,15 @@
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! - One-off error messages can be constructed using the `anyhow!` macro, which
|
||||
//! supports string interpolation and produces an `anyhow::Error`.
|
||||
//! - One-off error messages can be constructed using the `eyre!` macro, which
|
||||
//! supports string interpolation and produces an `eyre::ErrReport`.
|
||||
//!
|
||||
//! ```
|
||||
//! # use anyhow::{anyhow, Result};
|
||||
//! # use eyre::{eyre, Result};
|
||||
//! #
|
||||
//! # fn demo() -> Result<()> {
|
||||
//! # let missing = "...";
|
||||
//! return Err(anyhow!("Missing attribute: {}", missing));
|
||||
//! return Err(eyre!("Missing attribute: {}", missing));
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! ```
|
||||
@ -169,15 +169,15 @@
|
||||
//!
|
||||
//! ```toml
|
||||
//! [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
|
||||
//! `std::error::Error` trait which is only available through std, no_std mode
|
||||
//! will require an explicit `.map_err(Error::msg)` when working with a
|
||||
//! `std::error::ErrReport` trait which is only available through std, no_std mode
|
||||
//! 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.
|
||||
|
||||
#![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(not(feature = "std"), no_std)]
|
||||
#![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:
|
||||
///
|
||||
/// - `Error` requires that the error is `Send`, `Sync`, and `'static`.
|
||||
/// - `Error` guarantees that a backtrace is available, even if the underlying
|
||||
/// - `ErrReport` requires that the error is `Send`, `Sync`, and `'static`.
|
||||
/// - `ErrReport` guarantees that a backtrace is available, even if the underlying
|
||||
/// 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.
|
||||
///
|
||||
/// <br>
|
||||
@ -245,13 +245,13 @@ pub use anyhow as format_err;
|
||||
/// 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.
|
||||
/// 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
|
||||
/// 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 "{:#}".
|
||||
///
|
||||
/// ```console
|
||||
@ -269,12 +269,12 @@ pub use anyhow as format_err;
|
||||
/// No such file or directory (os error 2)
|
||||
///
|
||||
/// Stack backtrace:
|
||||
/// 0: <E as anyhow::context::ext::StdError>::ext_context
|
||||
/// at /git/anyhow/src/backtrace.rs:26
|
||||
/// 0: <E as eyre::context::ext::StdError>::ext_context
|
||||
/// at /git/eyre/src/backtrace.rs:26
|
||||
/// 1: core::result::Result<T,E>::map_err
|
||||
/// at /git/rustc/src/libcore/result.rs:596
|
||||
/// 2: anyhow::context::<impl anyhow::Context<T,E> for core::result::Result<T,E>>::with_context
|
||||
/// at /git/anyhow/src/context.rs:58
|
||||
/// 2: eyre::context::<impl eyre::Context<T,E> for core::result::Result<T,E>>::with_context
|
||||
/// at /git/eyre/src/context.rs:58
|
||||
/// 3: testing::main
|
||||
/// at src/main.rs:5
|
||||
/// 4: std::rt::lang_start
|
||||
@ -302,7 +302,7 @@ pub use anyhow as format_err;
|
||||
/// like this:
|
||||
///
|
||||
/// ```
|
||||
/// use anyhow::{Context, Result};
|
||||
/// use eyre::{Context, Result};
|
||||
///
|
||||
/// fn main() {
|
||||
/// if let Err(err) = try_main() {
|
||||
@ -319,21 +319,21 @@ pub use anyhow as format_err;
|
||||
/// # Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
pub struct Error {
|
||||
pub struct ErrReport {
|
||||
inner: ManuallyDrop<Box<ErrorImpl<()>>>,
|
||||
}
|
||||
|
||||
/// 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
|
||||
///
|
||||
/// ```
|
||||
/// use anyhow::Error;
|
||||
/// use eyre::ErrReport;
|
||||
/// 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() {
|
||||
/// if let Some(io_error) = cause.downcast_ref::<io::Error>() {
|
||||
/// 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
|
||||
/// [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
|
||||
/// use anyhow::Result;
|
||||
/// use eyre::Result;
|
||||
///
|
||||
/// # const IGNORE: &str = stringify! {
|
||||
/// 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> {...}
|
||||
/// // ^ equivalent to std::result::Result<T, OtherError>
|
||||
@ -387,7 +387,7 @@ pub struct Chain<'a> {
|
||||
/// #
|
||||
/// # impl Deserialize for ClusterMap {}
|
||||
/// #
|
||||
/// use anyhow::Result;
|
||||
/// use eyre::Result;
|
||||
///
|
||||
/// fn main() -> Result<()> {
|
||||
/// # return Ok(());
|
||||
@ -397,19 +397,19 @@ pub struct Chain<'a> {
|
||||
/// 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`.
|
||||
///
|
||||
/// This trait is sealed and cannot be implemented for types outside of
|
||||
/// `anyhow`.
|
||||
/// `eyre`.
|
||||
///
|
||||
/// <br>
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use anyhow::{Context, Result};
|
||||
/// use eyre::{Context, Result};
|
||||
/// use std::fs;
|
||||
/// use std::path::PathBuf;
|
||||
///
|
||||
@ -452,7 +452,7 @@ pub type Result<T, E = Error> = core::result::Result<T, E>;
|
||||
/// # Effect on downcasting
|
||||
///
|
||||
/// 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
|
||||
/// both of the following use cases:
|
||||
@ -468,7 +468,7 @@ pub type Result<T, E = Error> = core::result::Result<T, E>;
|
||||
/// be helpful.
|
||||
///
|
||||
/// ```
|
||||
/// # use anyhow::bail;
|
||||
/// # use eyre::bail;
|
||||
/// # use thiserror::Error;
|
||||
/// #
|
||||
/// # #[derive(Error, Debug)]
|
||||
@ -479,7 +479,7 @@ pub type Result<T, E = Error> = core::result::Result<T, E>;
|
||||
/// # bail!(SuspiciousError);
|
||||
/// # }
|
||||
/// #
|
||||
/// use anyhow::{Context, Result};
|
||||
/// use eyre::{Context, Result};
|
||||
///
|
||||
/// fn do_it() -> Result<()> {
|
||||
/// helper().context("Failed to complete the work")?;
|
||||
@ -508,7 +508,7 @@ pub type Result<T, E = Error> = core::result::Result<T, E>;
|
||||
/// the application.
|
||||
///
|
||||
/// ```
|
||||
/// # use anyhow::bail;
|
||||
/// # use eyre::bail;
|
||||
/// # use thiserror::Error;
|
||||
/// #
|
||||
/// # #[derive(Error, Debug)]
|
||||
@ -519,7 +519,7 @@ pub type Result<T, E = Error> = core::result::Result<T, E>;
|
||||
/// # bail!("no such file or directory");
|
||||
/// # }
|
||||
/// #
|
||||
/// use anyhow::{Context, Result};
|
||||
/// use eyre::{Context, Result};
|
||||
///
|
||||
/// fn do_it() -> Result<()> {
|
||||
/// 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 {
|
||||
/// 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
|
||||
C: Display + Send + Sync + 'static;
|
||||
|
||||
/// Wrap the error value with additional context that is evaluated lazily
|
||||
/// 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
|
||||
C: Display + Send + Sync + 'static,
|
||||
F: FnOnce() -> C;
|
||||
@ -557,7 +557,7 @@ pub trait Context<T, E>: context::private::Sealed {
|
||||
// Not public API. Referenced by macro-generated code.
|
||||
#[doc(hidden)]
|
||||
pub mod private {
|
||||
use crate::Error;
|
||||
use crate::ErrReport;
|
||||
use core::fmt::{Debug, Display};
|
||||
|
||||
#[cfg(backtrace)]
|
||||
@ -573,10 +573,10 @@ pub mod private {
|
||||
pub use crate::kind::BoxedKind;
|
||||
}
|
||||
|
||||
pub fn new_adhoc<M>(message: M) -> Error
|
||||
pub fn new_adhoc<M>(message: M) -> ErrReport
|
||||
where
|
||||
M: Display + Debug + Send + Sync + 'static,
|
||||
{
|
||||
Error::from_adhoc(message, backtrace!())
|
||||
ErrReport::from_adhoc(message, backtrace!())
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use anyhow::{bail, Result};
|
||||
/// # use eyre::{bail, Result};
|
||||
/// #
|
||||
/// # fn has_permission(user: usize, resource: usize) -> bool {
|
||||
/// # true
|
||||
@ -23,7 +23,7 @@
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
/// # use anyhow::{bail, Result};
|
||||
/// # use eyre::{bail, Result};
|
||||
/// # use thiserror::Error;
|
||||
/// #
|
||||
/// # const MAX_DEPTH: usize = 1;
|
||||
@ -50,13 +50,13 @@
|
||||
#[macro_export]
|
||||
macro_rules! bail {
|
||||
($msg:literal $(,)?) => {
|
||||
return $crate::private::Err($crate::anyhow!($msg));
|
||||
return $crate::private::Err($crate::eyre!($msg));
|
||||
};
|
||||
($err:expr $(,)?) => {
|
||||
return $crate::private::Err($crate::anyhow!($err));
|
||||
return $crate::private::Err($crate::eyre!($err));
|
||||
};
|
||||
($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
|
||||
///
|
||||
/// ```
|
||||
/// # use anyhow::{ensure, Result};
|
||||
/// # use eyre::{ensure, Result};
|
||||
/// #
|
||||
/// # fn main() -> Result<()> {
|
||||
/// # let user = 0;
|
||||
@ -82,7 +82,7 @@ macro_rules! bail {
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
/// # use anyhow::{ensure, Result};
|
||||
/// # use eyre::{ensure, Result};
|
||||
/// # use thiserror::Error;
|
||||
/// #
|
||||
/// # const MAX_DEPTH: usize = 1;
|
||||
@ -108,17 +108,17 @@ macro_rules! bail {
|
||||
macro_rules! ensure {
|
||||
($cond:expr, $msg:literal $(,)?) => {
|
||||
if !$cond {
|
||||
return $crate::private::Err($crate::anyhow!($msg));
|
||||
return $crate::private::Err($crate::eyre!($msg));
|
||||
}
|
||||
};
|
||||
($cond:expr, $err:expr $(,)?) => {
|
||||
if !$cond {
|
||||
return $crate::private::Err($crate::anyhow!($err));
|
||||
return $crate::private::Err($crate::eyre!($err));
|
||||
}
|
||||
};
|
||||
($cond:expr, $fmt:expr, $($arg:tt)*) => {
|
||||
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 = ();
|
||||
/// #
|
||||
/// use anyhow::{anyhow, Result};
|
||||
/// use eyre::{eyre, Result};
|
||||
///
|
||||
/// fn lookup(key: &str) -> Result<V> {
|
||||
/// 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_rules! anyhow {
|
||||
macro_rules! eyre {
|
||||
($msg:literal $(,)?) => {
|
||||
// Handle $:literal as a special case to make cargo-expanded code more
|
||||
// concise in the common case.
|
||||
@ -155,7 +155,7 @@ macro_rules! anyhow {
|
||||
($err:expr $(,)?) => ({
|
||||
use $crate::private::kind::*;
|
||||
let error = $err;
|
||||
(&error).anyhow_kind().new(error)
|
||||
(&error).eyre_kind().new(error)
|
||||
});
|
||||
($fmt:expr, $($arg:tt)*) => {
|
||||
$crate::private::new_adhoc(format!($fmt, $($arg)*))
|
||||
|
@ -1,4 +1,4 @@
|
||||
use anyhow::{bail, Result};
|
||||
use eyre::{bail, Result};
|
||||
use std::io;
|
||||
|
||||
pub fn bail_literal() -> Result<()> {
|
||||
|
@ -1,13 +1,13 @@
|
||||
use anyhow::Error;
|
||||
use eyre::ErrReport;
|
||||
|
||||
#[test]
|
||||
fn test_send() {
|
||||
fn assert_send<T: Send>() {}
|
||||
assert_send::<Error>();
|
||||
assert_send::<ErrReport>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sync() {
|
||||
fn assert_sync<T: Sync>() {}
|
||||
assert_sync::<Error>();
|
||||
assert_sync::<ErrReport>();
|
||||
}
|
||||
|
@ -6,8 +6,8 @@ fn test_backtrace() {}
|
||||
#[rustversion::nightly]
|
||||
#[test]
|
||||
fn test_backtrace() {
|
||||
use anyhow::anyhow;
|
||||
use eyre::eyre;
|
||||
|
||||
let error = anyhow!("oh no!");
|
||||
let error = eyre!("oh no!");
|
||||
let _ = error.backtrace();
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use anyhow::anyhow;
|
||||
use eyre::eyre;
|
||||
use std::error::Error as StdError;
|
||||
use std::io;
|
||||
use thiserror::Error;
|
||||
@ -12,7 +12,7 @@ struct MyError {
|
||||
#[test]
|
||||
fn test_boxed_str() {
|
||||
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!",
|
||||
@ -28,13 +28,13 @@ fn test_boxed_thiserror() {
|
||||
let error = MyError {
|
||||
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());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_boxed_anyhow() {
|
||||
let error = anyhow!("oh no!").context("it failed");
|
||||
let error = anyhow!(error);
|
||||
fn test_boxed_eyre() {
|
||||
let error = eyre!("oh no!").context("it failed");
|
||||
let error = eyre!(error);
|
||||
assert_eq!("oh no!", error.source().unwrap().to_string());
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use anyhow::{anyhow, Error};
|
||||
use eyre::{eyre, ErrReport};
|
||||
|
||||
fn error() -> Error {
|
||||
anyhow!(0).context(1).context(2).context(3)
|
||||
fn error() -> ErrReport {
|
||||
eyre!(0).context(1).context(2).context(3)
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1,11 +1,11 @@
|
||||
mod drop;
|
||||
|
||||
use crate::drop::{DetectDrop, Flag};
|
||||
use anyhow::{Context, Error, Result};
|
||||
use eyre::{Context, ErrReport, Result};
|
||||
use std::fmt::{self, Display};
|
||||
use thiserror::Error;
|
||||
|
||||
// https://github.com/dtolnay/anyhow/issues/18
|
||||
// https://github.com/dtolnay/eyre/issues/18
|
||||
#[test]
|
||||
fn test_inference() -> Result<()> {
|
||||
let x = "1";
|
||||
@ -56,7 +56,7 @@ impl Dropped {
|
||||
}
|
||||
}
|
||||
|
||||
fn make_chain() -> (Error, Dropped) {
|
||||
fn make_chain() -> (ErrReport, Dropped) {
|
||||
let dropped = Dropped {
|
||||
low: Flag::new(),
|
||||
mid: Flag::new(),
|
||||
@ -77,7 +77,7 @@ fn make_chain() -> (Error, Dropped) {
|
||||
.unwrap_err();
|
||||
|
||||
// impl Context for Result<T, Error>
|
||||
let high = Err::<(), Error>(mid)
|
||||
let high = Err::<(), ErrReport>(mid)
|
||||
.context(HighLevel {
|
||||
message: "failed to start server",
|
||||
drop: DetectDrop::new(&dropped.high),
|
||||
|
@ -1,13 +1,13 @@
|
||||
mod drop;
|
||||
|
||||
use self::drop::{DetectDrop, Flag};
|
||||
use anyhow::{Error, Result};
|
||||
use eyre::{ErrReport, Result};
|
||||
use std::error::Error as StdError;
|
||||
|
||||
#[test]
|
||||
fn test_convert() {
|
||||
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);
|
||||
assert_eq!("oh no!", box_dyn.to_string());
|
||||
drop(box_dyn);
|
||||
|
@ -3,7 +3,7 @@ mod drop;
|
||||
|
||||
use self::common::*;
|
||||
use self::drop::{DetectDrop, Flag};
|
||||
use anyhow::Error;
|
||||
use eyre::ErrReport;
|
||||
use std::error::Error as StdError;
|
||||
use std::fmt::{self, Display};
|
||||
use std::io;
|
||||
@ -71,7 +71,7 @@ fn test_downcast_mut() {
|
||||
#[test]
|
||||
fn test_drop() {
|
||||
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());
|
||||
assert!(has_dropped.get());
|
||||
}
|
||||
@ -90,7 +90,7 @@ fn test_large_alignment() {
|
||||
|
||||
impl StdError for LargeAlignedError {}
|
||||
|
||||
let error = Error::new(LargeAlignedError("oh no!"));
|
||||
let error = ErrReport::new(LargeAlignedError("oh no!"));
|
||||
assert_eq!(
|
||||
"oh no!",
|
||||
error.downcast_ref::<LargeAlignedError>().unwrap().0
|
||||
|
@ -1,4 +1,4 @@
|
||||
use anyhow::{bail, Context, Result};
|
||||
use eyre::{bail, Context, Result};
|
||||
use std::io;
|
||||
|
||||
fn f() -> Result<()> {
|
||||
|
@ -1,7 +1,7 @@
|
||||
mod common;
|
||||
|
||||
use self::common::*;
|
||||
use anyhow::ensure;
|
||||
use eyre::ensure;
|
||||
|
||||
#[test]
|
||||
fn test_messages() {
|
||||
|
@ -1,29 +1,29 @@
|
||||
mod drop;
|
||||
|
||||
use self::drop::{DetectDrop, Flag};
|
||||
use anyhow::Error;
|
||||
use eyre::ErrReport;
|
||||
use std::marker::Unpin;
|
||||
use std::mem;
|
||||
|
||||
#[test]
|
||||
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]
|
||||
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]
|
||||
fn test_autotraits() {
|
||||
fn assert<E: Unpin + Send + Sync + 'static>() {}
|
||||
assert::<Error>();
|
||||
assert::<ErrReport>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_drop() {
|
||||
let has_dropped = Flag::new();
|
||||
drop(Error::new(DetectDrop::new(&has_dropped)));
|
||||
drop(ErrReport::new(DetectDrop::new(&has_dropped)));
|
||||
assert!(has_dropped.get());
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use anyhow::anyhow;
|
||||
use eyre::eyre;
|
||||
use std::error::Error as StdError;
|
||||
use std::fmt::{self, Display};
|
||||
use std::io;
|
||||
@ -26,37 +26,37 @@ impl StdError for TestError {
|
||||
|
||||
#[test]
|
||||
fn test_literal_source() {
|
||||
let error = anyhow!("oh no!");
|
||||
let error = eyre!("oh no!");
|
||||
assert!(error.source().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_variable_source() {
|
||||
let msg = "oh no!";
|
||||
let error = anyhow!(msg);
|
||||
let error = eyre!(msg);
|
||||
assert!(error.source().is_none());
|
||||
|
||||
let msg = msg.to_owned();
|
||||
let error = anyhow!(msg);
|
||||
let error = eyre!(msg);
|
||||
assert!(error.source().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fmt_source() {
|
||||
let error = anyhow!("{} {}!", "oh", "no");
|
||||
let error = eyre!("{} {}!", "oh", "no");
|
||||
assert!(error.source().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_io_source() {
|
||||
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());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_anyhow_from_anyhow() {
|
||||
let error = anyhow!("oh no!").context("context");
|
||||
let error = anyhow!(error);
|
||||
fn test_eyre_from_eyre() {
|
||||
let error = eyre!("oh no!").context("context");
|
||||
let error = eyre!(error);
|
||||
assert_eq!("oh no!", error.source().unwrap().to_string());
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
use anyhow::anyhow;
|
||||
use eyre::eyre;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Error;
|
||||
|
||||
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
|
||||
|
|
||||
7 | let _ = anyhow!(Error);
|
||||
| ^^^^^^^^^^^^^^ method not found in `&Error`
|
||||
7 | let _ = eyre!(Error);
|
||||
| ^^^^^^^^^^^^ method not found in `&Error`
|
||||
|
|
||||
= note: the method `anyhow_kind` exists but the following trait bounds were not satisfied:
|
||||
`&Error : anyhow::kind::AdhocKind`
|
||||
`&Error : anyhow::kind::TraitKind`
|
||||
`Error : anyhow::kind::TraitKind`
|
||||
= note: the method `eyre_kind` exists but the following trait bounds were not satisfied:
|
||||
`&Error : eyre::kind::AdhocKind`
|
||||
`&Error : eyre::kind::TraitKind`
|
||||
`Error : eyre::kind::TraitKind`
|
||||
= 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:
|
||||
candidate #1: `anyhow::kind::AdhocKind`
|
||||
candidate #2: `anyhow::kind::TraitKind`
|
||||
candidate #3: `anyhow::kind::BoxedKind`
|
||||
= note: the following traits define an item `eyre_kind`, perhaps you need to implement one of them:
|
||||
candidate #1: `eyre::kind::AdhocKind`
|
||||
candidate #2: `eyre::kind::TraitKind`
|
||||
candidate #3: `eyre::kind::BoxedKind`
|
||||
= 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