#error #derive-error #trace #tracing #error-handling #derive

nightly no-std errore

Library for error handling and tracing

6 releases (3 breaking)

0.4.1 Nov 25, 2024
0.4.0 Nov 23, 2024
0.3.0 Oct 29, 2024
0.2.0 Oct 29, 2024
0.1.1 Oct 27, 2024

#1090 in Rust patterns

Download history 115/week @ 2024-10-21 201/week @ 2024-10-28 4/week @ 2024-11-04 126/week @ 2024-11-18 188/week @ 2024-11-25 4/week @ 2024-12-09

318 downloads per month

MIT/Apache

120KB
2.5K SLoC

Errore

crates.io docs.rs build status rustc version

This library provides a framework to handle and trace errors across modules and crates.

At the moment errore is in development and breaking changes are to be expected.


Example


At first glance, errore its error definition looks quite similar to thiserror`s:

use errore::prelude::*;

use crate::auth;

/// Errors for account related operations.
#[derive(Error, Debug)]
pub enum Error {
    #[error(transparent)]
    Authentication(#[from] auth::Ec),
    #[error("Submitted captcha '{hash}' is wrong")]
    WrongCaptcha { hash: String },
    #[error("Captcha session '{session}' was not found or is expired")]
    InvalidCaptcha { session: String },
}

// Automatically generated:
// pub struct Ec(pub Span<Error>)

pub fn login(email: &str, password: &str) -> Result<(), Ec> {
    auth::verify(email, password)?;
    // errors can also be defined without err!() macro
    Err(Ec::new(Error::WrongCaptcha {
        hash: "abc123".into(),
    }))
}

However, it is possible to extract additional information from the error, as shown in this sample error output:

Error: example_basic::account::Authentication
├─▶ <example_basic::auth::ReadPassword> Invalid email or password
│   ├╴ examples/basic/src/auth.rs:20:8
│   ╰╴ examples/basic/src/auth.rs:24:8
│
╰─▶ <example_basic::account::Authentication>
    ╰╴ examples/basic/src/account.rs:20:5

Trace records:
<example_basic::auth::ReadPassword> Invalid email or password at examples/basic/src/auth.rs:20:8
<example_basic::auth::ReadPassword> Invalid email or password at examples/basic/src/auth.rs:24:8
<example_basic::account::Authentication> Invalid email or password at examples/basic/src/account.rs:20:5

Error display:
example_basic::account::Authentication: Invalid email or password
    at examples/basic/src/auth.rs:20:8

Error extraction with 'match':
OS error code 2: entity not found

Error extraction with 'get()':
OS error code 2: entity not found

The complete example can be seen here. For other examples please see here.


Features

  • Tracing capability with rich metadata such as file location and line number without backtrace
  • Generates trait implementations for metadata and error conversion
  • Customizable Subscriber and Formatter interface
  • Support for user attached data with Extensions at subscriber
  • Partial API compatibility with thiserror that allows to optionally enable errore in public distributed libraries on stable rust.
    See example
  • Usable in application and library code
  • no-std support & wasmcompatible

Limitations & Disadvantages

  • Invasive code changes with Result instrumentation are required
  • Nightly compiler is required
  • Only one error per module can be defined
  • No recursive or self-referencing fields
  • Error conversion with attribute macro #from requires a trait implementation of std::error::Error for the type
  • Generics with traits in error fields need to be declared with the where keyword
  • Some edge cases cannot be expressed with generics (for e.g. nesting)
  • No anyhow support (shouldn't be a problem if errore is used)

Recommendations

  • For public libraries an optional feature flag for errore is advisable. For the best results thiserror should be used.
    See Example
  • For private libraries errore can be used as is. Errors can be declared on a per module basis or as one global type.
    See Example
  • For general best-practices with errore the various examples can serve as a good foundation

Feature flags

  • ctor: Utilizes link_sections provided by the ctor and inventory crates to offer a better implementation of the metadata and subscriber relevant code. The fallback implementation is based on lazy static variables. This feature can be disabled at no-std projects on build failures.
  • debug-no-std: Enables internal logging with the defmt crate to debug errore itself.
  • debug-std: Enables internal logging with the log crate to debug errore itself.
  • std: Enables standard library support. If the std feature is not enabled, the alloc crate is required.

Thanks to

  • @dtolnay - Maintainer of several great crates including thiserror which is used as errore`s foundation
  • tracing / error-stack / error_set maintainers & contributors for the inspiring codebase and ideas

Dependencies

~2.3–3.5MB
~61K SLoC