2 unstable releases

0.2.0 May 7, 2023
0.1.0 Aug 20, 2022

#784 in Debugging


Used in 2 crates

MIT/Apache

12KB
105 lines

logerr

Seamless error type logging.

What does it do?

logerr aims to make logging errors as part of a std::result::Result easy and obstruction-free. It provides a trait, LoggableError, that is implemented on a rich variety of common Result variants. All the traits functions share the special property that they pass through the Result type unmodified.

This way, regular error handling is not obstructed in any way, and logging can happen while you're "on the go" handling errors.

How to use it

Once you have a Result with a supported error type, you just do:

use anyhow::{anyhow, Context};
use logerr::LoggableError;  // Must include to get access to trait functions

fn main() {
    Err(anyhow!("an error occured"))
        .context("this is just a demo")
        .to_stderr()                     // <-- Magic!
        .unwrap()
}

There are various feature flags that control the behavior of logging. By default, LoggableError uses a generic implementation over all error types implementing Error and prints errors using their Display impl, printing an error chain if Error::source() is implemented.

If you want to make use of more advanced features, or add special implementations for your own error types (including custom logging), disable the default features and implement the trait yourself.

Feature flags

Feature compatibility matrix

Below you see a matrix representation of the features that can safely be combined with each other. An X means that the features can be combined.

log anyhow generic
log X X
anyhow X
generic X

Choosing which features to use

I only want to log errors!

In this case the default features (log, generic) are very likely sufficient for you

I want to bring my own error formatting, completely!

This is currently only possible for error types that you or your code owns (Due to the orphan rule). In this case, forego all default features and implement the LoggableError trait yourself. You can have a look at the source code if you need inspiration.

I'm using anyhow for all my error handling!

Use the anyhow feature flag, and you're good to go.

log

Pulls in the log crate and adds a default implementation for to_log that prints the error to log::error!.

Note: The logged message will not contain module information about the module where it was invoked. This is a shortcoming of the Rust language and will be fixed once #87417 is merged.

anyhow

Pulls in the anyhow crate and adds an implementation specifically for anyhow::Result (i.e. Result<_, anyhow::Error) that prints the whole error chain with the default anyhow Debug formatting. Your application must use the anyhow::Result type for this to work

generic

Adds a generic implementation of the LoggableError trait for all error types that implement the Error trait. The result looks like this:

ERROR: an error occured
because: something bad happened
because: file doesn't exist

The root cause is the last error printed.

Dependencies

~120KB