A failure-like derive macro for the std Error .

The source code is mostly copied from failure-derive .

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

implementation Derive Error implementation (implementing source to return the cause of the error)

Planned features

Derive From<OtherError> implementations

Usage

Cargo.toml:

[dependencies] err-derive = "0.1"

Rust code:

#[macro_use] extern crate err_derive; use std::error::Error; use std::path::PathBuf; #[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(cause)] FormatError), #[error(display = "could not find file: {:?}", path)] NotFound { path: PathBuf }, } impl From<FormatError> for LoadingError { fn from(f: FormatError) -> Self { LoadingError::FormatError(f) } } fn main() { let my_error: LoadingError = FormatError::MissingAttribute("some_attr".to_owned()).into(); print_error(&my_error); } 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(); } }

Credit