#derive #error #display

macro err-derive

Derive macro for std::error::Error

11 releases

✓ Uses Rust 2018 edition

0.2.3 Mar 5, 2020
0.2.2 Jan 16, 2020
0.2.1 Oct 10, 2019
0.1.6 Sep 26, 2019
0.1.4 Dec 27, 2018

#21 in Rust patterns

Download history 8674/week @ 2019-12-02 7509/week @ 2019-12-09 6967/week @ 2019-12-16 3559/week @ 2019-12-23 4157/week @ 2019-12-30 7209/week @ 2020-01-06 6682/week @ 2020-01-13 5581/week @ 2020-01-20 5657/week @ 2020-01-27 5673/week @ 2020-02-03 5942/week @ 2020-02-10 6097/week @ 2020-02-17 6684/week @ 2020-02-24 6415/week @ 2020-03-02 7536/week @ 2020-03-09 7924/week @ 2020-03-16

25,436 downloads per month
Used in 129 crates (62 directly)

MIT/Apache

20KB
273 lines

err-derive

Build status Crates.io API Docs

A failure-like derive macro for the std Error. The source code is mostly copied from failure-derive.

Minimum Rust version: 1.34.0

Motivation

Why yet another error handling library? There already are dozen others, the most popular being:

The former provides a nice #[derive(Fail)] macro, but it uses its own error type (Fail) and its usage is rather discouraged since std::error::Error is getting fixed to provide the same benefits as Fail.

error-chain does support std::error::Error, but it uses a declarative for generating the error implementation which makes the syntax too obscure in my opinion.

This crate tries to combine both advantages:

  • work with std::error::Error
  • provide a custom #[derive(Error)] that works just like failure-derive

err-derive is compatible with std, including the recent change to deprecate Error::cause in favour of Error::source, and provides an easy syntax for generating the Display and Error boilerplate (the latter being 99% copied from failure-derive).

Features

err-derive can be applied to your error struct / enum and does the following for you:

  • Derive Display implementation
  • Derive Error implementation (implementing source to return the cause of the error)
  • Derive From<OtherError> implementations

Usage

Cargo.toml:

[dependencies]
err-derive = "0.1"

Rust code:

#[cfg(feature = "std")]
use std::error::Error;
#[cfg(not(feature = "std"))]
use std::fmt::Display;
use std::path::PathBuf;

use err_derive::Error;

#[derive(Debug, Error)]
pub enum FormatError {
    #[error(display = "invalid header (expected: {:?}, got: {:?})", expected, found)]
    InvalidHeader {
        expected: String,
        found: String,
    },
    #[error(display = "missing attribute: {:?}", _0)]
    MissingAttribute(String),
}

#[derive(Debug, Error)]
pub enum LoadingError {
    #[error(display = "could not decode file")]
    FormatError(#[error(source)] FormatError),
    #[error(display = "could not find file: {:?}", path)]
    NotFound { path: PathBuf },
}

fn main() {
    let my_error: LoadingError = FormatError::MissingAttribute("some_attr".to_owned()).into();

    print_error(&my_error);
}

#[cfg(feature = "std")]
fn print_error(e: &dyn Error) {
    eprintln!("error: {}", e);
    let mut cause = e.source();
    while let Some(e) = cause {
        eprintln!("caused by: {}", e);
        cause = e.source();
    }
}

#[cfg(not(feature = "std"))]
fn print_error(e: &dyn Display) {
    eprintln!("error: {}", e);
}

no_std

You can use this library in your #![no_std] projects by disabling the default std feature.

[dependencies]
err-derive = { version = "...", default-features = false }

Without the default std feature, only the From and Display implementations are derived, as Error requires std.

Credit

Credit goes to @withoutboats and other contributors of failure.

License

This project is dual-licensed under Apache-2.0 / MIT. You're free to choose one of both licenses. Every contribution made to this project is assumed to be licensed according to these terms.

See LICENSE, LICENSE-MIT and LICENSE-APACHE for more information.

Dependencies

~0.6–1MB
~21K SLoC