mirror of
https://github.com/eyre-rs/eyre.git
synced 2025-09-27 13:01:29 +00:00
Update docs a little
This commit is contained in:
parent
82bf2a66e6
commit
3b26dacea8
11
Cargo.toml
11
Cargo.toml
@ -1,18 +1,15 @@
|
||||
[package]
|
||||
name = "eyre"
|
||||
version = "1.0.26" # remember to update html_root_url
|
||||
authors = ["David Tolnay <dtolnay@gmail.com>"]
|
||||
version = "0.2.0" # remember to update html_root_url
|
||||
authors = ["David Tolnay <dtolnay@gmail.com>", "Jane Lusby <jlusby42@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/eyre"
|
||||
description = "Flexible concrete Error Handling and Reporting type built on std::error::Error"
|
||||
repository = "https://github.com/yaahc/eyre"
|
||||
documentation = "https://docs.rs/eyre"
|
||||
readme = "README.md"
|
||||
categories = ["rust-patterns"]
|
||||
|
||||
[badges]
|
||||
travis-ci = { repository = "dtolnay/eyre" }
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
std = []
|
||||
|
133
README.md
133
README.md
@ -1,7 +1,7 @@
|
||||
Eyre ¯\\\_(ツ)\_/¯
|
||||
=========================
|
||||
|
||||
[](https://travis-ci.com/dtolnay/eyre)
|
||||
[![Build Status][actions-badge]][actions-url]
|
||||
[](https://crates.io/crates/eyre)
|
||||
[](https://docs.rs/eyre)
|
||||
|
||||
@ -9,11 +9,134 @@ This library provides [`eyre::ErrReport`][ErrReport], a trait object based
|
||||
error handling type for easy idiomatic error handling and reporting in Rust
|
||||
applications.
|
||||
|
||||
First and foremost, this crate is a fork of `anyhow` by @dtolnay. My goal in
|
||||
writing this crate is to explore new directions of handling context and to
|
||||
explore new ways to communicate the intended usage of this crate via changes to
|
||||
the API.
|
||||
|
||||
The main changes this crate brings to anyhow are
|
||||
|
||||
* Addition of the [`eyre::EyreContext`] trait and a type parameter on the core error
|
||||
handling type which users can use to insert custom forms of context into
|
||||
their general error type.
|
||||
* Rebranding the type as principally for error reporting, rather than
|
||||
describing it as an error type in its own right. This type is not an error,
|
||||
it contains errors that it masqerades as, and provides helpers for creating
|
||||
new errors to wrap those errors and for displaying those chains of errors,
|
||||
and the included context, to the end user. The goal is to make it obvious
|
||||
that this type is meant to be used when the only way you expect to handle
|
||||
errors is to print them.
|
||||
* Changing the [`anyhow::Context`] trait to [`eyre::WrapErr`] to make it clear
|
||||
that it is unrelated to the [`eyre::EyreContext`] and the context member, and
|
||||
is only for inserting new errors into the chain of errors.
|
||||
* Addition of a new `context` function on [`eyre::ErrReport`] to assist with
|
||||
extracting members from the inner Context, which is used by
|
||||
[`eyre::ErrReport`] to extract [`std::backtrace::Backtrace`]'s from generic
|
||||
contexts types.
|
||||
|
||||
These changes were made in order to facilitate the usage of
|
||||
[`tracing::SpanTrace`] with anyhow, which is a Backtrace-like type for
|
||||
rendering custom defined runtime context.
|
||||
|
||||
**Note**: The way the `eyre!` macro works in practice differs from how
|
||||
`anyhow!` works due to the addition of the generic type parameter. In anyhow
|
||||
the following is valid.
|
||||
|
||||
```rust
|
||||
let val = get_optional_val.ok_or_else(|| anyhow!("failed to get value)).unwrap();
|
||||
```
|
||||
|
||||
Where as with `eyre!` this will fail due to being unable to infer the type for
|
||||
the Context parameter. The solution to this problem, should you encounter it,
|
||||
is to give the compiler a hint for what type it should be resolving to, either
|
||||
via your return type or a type annotation.
|
||||
|
||||
```rust
|
||||
// Will work fine
|
||||
let val: ErrReport = get_optional_val.ok_or_else(|| eyre!("failed to get value)).unwrap();
|
||||
```
|
||||
|
||||
[ErrReport]: https://docs.rs/eyre/1.0/eyre/struct.ErrReport.html
|
||||
[actions-badge]: https://github.com/yaahc/eyre/workflows/ci/badge.svg
|
||||
[actions-url]:https://github.com/yaahc/eyre/actions?query=workflow%3Aci
|
||||
|
||||
## Customization
|
||||
|
||||
In order to insert your own custom context type you must first implement the
|
||||
`eyre::EyreContext` trait for said type, which has four required methods.
|
||||
|
||||
* `fn default(error: &Error) -> Self` - For constructing default context while
|
||||
allowing special case handling depending on the content of the error you're
|
||||
wrapping.
|
||||
|
||||
This is essentially `Default::default` but more flexible, for example, the
|
||||
`eyre::DefaultContext` type provide by this crate uses this to only capture a
|
||||
`Backtrace` if the inner `Error` does not already have one.
|
||||
|
||||
```rust
|
||||
fn default(error: &(dyn StdError + 'static)) -> Self {
|
||||
let backtrace = backtrace_if_absent!(error);
|
||||
|
||||
Self { backtrace }
|
||||
}
|
||||
```
|
||||
|
||||
* `fn context_raw(&self, typeid TypeID) -> Option<&dyn Any>` - For extracting
|
||||
arbitrary members from a context based on their type.
|
||||
|
||||
This method is like a flexible version of the `fn backtrace(&self)` method on
|
||||
the `Error` trait. In the future we will likely support extracting `Backtrace`s
|
||||
and `SpanTrace`s by default by relying on the implementation of `context_raw`
|
||||
provided by the user.
|
||||
|
||||
|
||||
Here is how the `eyre::DefaultContext` type uses this to return `Backtrace`s.
|
||||
|
||||
```rust
|
||||
fn context_raw(&self, typeid: TypeId) -> Option<&dyn Any> {
|
||||
if typeid == TypeId::of::<Backtrace>() {
|
||||
self.backtrace.as_ref().map(|b| b as &dyn Any)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
* `fn debug(&self, error: &(dyn Error + 'static), f: &mut fmt::Formatter<'_>) -> fmt Result`
|
||||
it's companion `display` version. - For formatting the entire error chain and
|
||||
the user provided context.
|
||||
|
||||
When overriding the context it no longer makes sense for `eyre::ErrReport` to
|
||||
provide the `Display` and `Debug` implementations for the user, becase we
|
||||
cannot predict what forms of context you will need to display along side your
|
||||
chain of errors. Instead we forward the implementations of `Display` and
|
||||
`Debug` to these methods on the inner `EyreContext` type.
|
||||
|
||||
This crate does provide a few helpers to assist in writing display
|
||||
implementations, specifically the `Chain` type, for treating an error and its
|
||||
sources like an iterator, and the `Indented` type, for indenting multi line
|
||||
errors consistently without using heap allocations.
|
||||
|
||||
**Note**: best practices for printing errors suggest that `{}` should only
|
||||
print the current error and none of its sources, and that the primary method of
|
||||
displaying an error, its sources, and its context should be handled by the
|
||||
`Debug` implementation, which is what is used to print errors that are returned
|
||||
from `main`. For examples on how to implement this please refer to the
|
||||
implementations of `display` and `debug` on `eyre::DefaultContext`
|
||||
|
||||
Once you've defined a custom Context type you can use it throughout your
|
||||
application by defining a type alias.
|
||||
|
||||
```rust
|
||||
type ErrReport = eyre::ErrReport<MyContext>;
|
||||
|
||||
// And optionally...
|
||||
type Result<T, E = eyre::ErrReport<MyContext>> = core::result::Result<T, E>;
|
||||
```
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
eyre = "1.0"
|
||||
eyre = "0.2"
|
||||
```
|
||||
|
||||
*Compiler support: requires rustc 1.34+*
|
||||
@ -110,13 +233,17 @@ eyre = "1.0"
|
||||
|
||||
## No-std support
|
||||
|
||||
**NOTE**: tests are currently broken for `no_std` so I cannot guaruntee that
|
||||
everything works still. I'm waiting for upstream fixes to be merged rather than
|
||||
fixing them myself, so bear with me.
|
||||
|
||||
In no_std mode, the same API is almost all available and works the same way. To
|
||||
depend on Eyre in no_std mode, disable our default enabled "std" feature in
|
||||
Cargo.toml. A global allocator is required.
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
eyre = { version = "1.0", default-features = false }
|
||||
eyre = { version = "0.2", default-features = false }
|
||||
```
|
||||
|
||||
Since the `?`-based error conversions would normally rely on the
|
||||
|
13
src/lib.rs
13
src/lib.rs
@ -169,7 +169,7 @@
|
||||
//!
|
||||
//! ```toml
|
||||
//! [dependencies]
|
||||
//! eyre = { version = "1.0", default-features = false }
|
||||
//! eyre = { version = "0.2", default-features = false }
|
||||
//! ```
|
||||
//!
|
||||
//! Since the `?`-based error conversions would normally rely on the
|
||||
@ -177,7 +177,7 @@
|
||||
//! will require an explicit `.map_err(ErrReport::msg)` when working with a
|
||||
//! non-Eyre error type inside a function that returns Eyre's error type.
|
||||
|
||||
#![doc(html_root_url = "https://docs.rs/eyre/1.0.26")]
|
||||
#![doc(html_root_url = "https://docs.rs/eyre/0.2.0")]
|
||||
#![cfg_attr(backtrace, feature(backtrace))]
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
#![allow(
|
||||
@ -364,10 +364,11 @@ impl EyreContext for DefaultContext {
|
||||
Self { backtrace }
|
||||
}
|
||||
|
||||
fn context_raw(&self, typid: TypeId) -> Option<&dyn Any> {
|
||||
match typid {
|
||||
t if t == TypeId::of::<Backtrace>() => self.backtrace.as_ref().map(|b| b as &dyn Any),
|
||||
_ => None,
|
||||
fn context_raw(&self, typeid: TypeId) -> Option<&dyn Any> {
|
||||
if typeid == TypeId::of::<Backtrace>() {
|
||||
self.backtrace.as_ref().map(|b| b as &dyn Any)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user