3 releases

Uses old Rust 2015

0.1.2 Nov 11, 2017
0.1.1 Nov 11, 2017
0.1.0 Nov 11, 2017

#38 in #derive-error


Used in 2 crates

MIT/Apache

13KB
146 lines

Yet Another Derive Error (Yade)

Yade is a set of derive macros designed to generate the boilerplate around using the Error trait in Rust. This crate supports enum, struct, unit, tuple struct, and ErrorKind styled Error types.

Yade does not set out to solve any of the problems with the Rust Error trait. If you are interested in an alternative trait for error handling that attempts to address the shortcomings of Error, please check out the Failure project.

Usage

Be sure to add the yade crate to your Cargo.toml:

[dependencies]
yade = "*"

Derive Macros

Yade provides two derive macros, YadeError ad YadeKind.

YadeError is the primary macro and can be used to automatically derive the Error and Display traits for many kinds of error structs.

For example:

#[macro_use] extern crate yade;
use std::fs::File;
use std::error::Error as StdError;

#[derive(Debug, YadeError)]
pub enum Error {
    #[display(msg = "File could not be found: {}", _0)]
    FileNotFound(String, #[cause] std::io::Error),

    #[display(msg = "Bad request: {}", params)]
    BadRequest {
        params: String,
    },
}

fn causes_error() -> Result<(), Error> {
    File::open("a_missing_file.txt")
        .map_err(|e| Error::FileNotFound("a_missing_file.txt".into(), e))?;

    Ok(())
}

fn main() {
    match causes_error() {
      Err(err) => {
          eprintln!("An error occured: {}", err);

          let mut err: &StdError = &err;
          while let Some(cause) = err.cause() {
              eprintln!(" - Cause: {}", cause);
              err = cause;
          }
      },
      _ => println!("Great success"),
    }
}

YadeKind is provided to assist in building error types using an ErrorKind enum.

#[macro_use] extern crate yade;
use std::fs::File;
use std::error::Error as StdError;

#[derive(Debug, YadeError)]
#[display(msg = "{}", kind)]
pub struct Error {
    pub kind: ErrorKind,

    #[cause]
    pub cause: Option<Box<StdError>>,
}

#[derive(Debug, YadeKind)]
pub enum ErrorKind {
    #[display(msg = "File could not be found: {}", _0)]
    FileNotFound(String),

    #[display(msg = "World fell apart, oops")]
    AnotherError,
}

fn causes_error() -> Result<(), Error> {
    File::open("a_missing_file.txt")
        .map_err(|e| Error { kind: ErrorKind::FileNotFound("a_missing_file.txt".into()), cause: Some(Box::new(e)) })?;

    Ok(())
}

fn main() {
    match causes_error() {
        Err(err) => {
            eprintln!("An error occured: {}", err);

            let mut err: &StdError = &err;
            while let Some(cause) = err.cause() {
                eprintln!(" - Cause: {}", cause);
                err = cause;
            }
        },

        _ => println!("Great success"),
    }
}

FAQ

Why not just use 'failure'?

I highly encourage that you check out the failure crate by withoutboats as it tries to solve many of the problems of the existing Error trait. It is currently still in early development, but I do believe that 'failure' or something like it will end up being the future of error handling in rust.

Having said that, 'failure' is better off used in new libraries and applications which have not already standardized around the Rust standard library Error trait.

Yade is designed to be a drop-in replacement that maintains compatibility with older code.

Why not just use 'error-chain'?

I have used error-chain in several projects since it's inception and while I do think it's a useful tool for building applications, I do not feel it fits in well for libraries.

My main complaint is that 'chain-chain' complicates pattern matching. I also find the macro based DSLs like the one employed by 'chain-error' are confusing to the error when dealing with syntax errors. (There is the derive-error-chain project, but I feel that it suffers from some of it's own issues.)

Similar Libraries

  • failure - A new error management story.
  • error_def - A Rust syntax extension for generating error-handling boilerplate code.
  • derive-error - Derive macro for Error using macros 1.1.
  • error-chain - Yet another error boilerplate library.

License

Yade is licensed under either of

Contributing

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Please see the CONTRIBUTING file for more information.

Dependencies

~2MB
~43K SLoC