This library provides a wrapper around a [thiserror] enum, from which you can add additional context, similar to how you would with the [anyhow] crate.
This crate is meant to bridge the gap and provide the best of both worlds between [thiserror] and [anyhow], in that you retain the type of the underlying root error, while allowing you to add additional context to it.
Problem
With [thiserror]
Using [thiserror], you can end up with errors similar to
Sqlx(RowNotFound)
which is not helpful in debugging.
With [anyhow]
Using [anyhow] gives you much more helpful context:
Sqlx(RowNotFound)
Caused by:
0: loading user id 1
1: authentication
But it comes at the expense of erasing the underlying error type.
This type erasure is problematic in a few ways:
- if you want to preserve the ability to use your [thiserror] type, it forces you to convert all your errors in your [thiserror] type. This is particularly easy to forget to do, as [anyhow] will happily accept any error.
- if you forget to convert an error into your [thiserror] type and you want to have something approximating the match on your [thiserror] type, then you need to attempt to downcast all the possible variants of the [thiserror] type. In turn, that means you need to add a downcast attempt for any new variants you add to your [thiserror] type. This introduces an easy thing to forget to do.
In a happy case, if you remember to convert all your errors into your [thiserror] type, then you can downcast directly to the [thiserror] type.
use Context;
use Error;
async
async
But, if you forget to convert your error into your [thiserror] type, then things start to get messy.
use Context;
use Error;
async
async
Solution
This crate bridges the two worlds, allowing you to add context to your [thiserror] type while preserving the ergonomics and accessibility of the underlying error enum.
This crate is intended to be used with [thiserror] enums, but should work with any error type.
** Example **
use Error;
use ;
// A normal, run-of-the-mill thiserror enum
// Defines a new type, `ThisErr`, that wraps `ThisErrorInner` and allows
// additional context to be added.
impl_context!;
// We are returning the wrapped new type, `ThisError`, instead of the
// underlying `ThisErrorInner`.
async
async
Usage
Similar to [context], this crate provides a [Context] trait that extends
the [Result] type with two methods: context
and with_context
.
context adds static context to the error, while with_context adds dynamic context to the error.
use Error;
use ;
impl_context!;
let res = t;
assert!;
let err = res.unwrap_err;
let debug_repr = format!;
assert_eq!;
Nesting
Context enriched errors can be nested and they will preserve their context messages when converting from a child error type to a parent.
See [impl_from_carry_context] for more information.