derive-error-chain 0.8.0

A Macros 1.1 implementation of error-chain

Crate derive_error_chain [] [src]

A Macros 1.1 implementation of https://crates.io/crates/error-chain

The error-chain example

mod other_error {
    error_chain! {}
}

error_chain {
    types { Error, ErrorKind, ResultExt, Result; }

    links {
        Another(other_error::Error, other_error::ErrorKind) #[cfg(unix)];
    }

    foreign_links {
        Fmt(::std::fmt::Error);
        Io(::std::io::Error) #[cfg(unix)];
    }

    errors {
        InvalidToolchainName(t: String) {
            description("invalid toolchain name")
            display("invalid toolchain name: '{}'", t)
        }
    }
}

becomes

mod other_error {
    #[derive(Debug, error_chain)]
    pub enum ErrorKind {
        Msg(String),
    }
}

#[derive(Debug, error_chain)]
pub enum ErrorKind {
    Msg(String),

    #[cfg(unix)]
    #[error_chain(link = "other_error::Error")]
    Another(other_error::ErrorKind),

    #[error_chain(foreign)]
    Fmt(::std::fmt::Error),

    #[cfg(unix)]
    #[error_chain(foreign)]
    Io(::std::io::Error),

    #[error_chain(custom, description = "invalid_toolchain_name_error_description", display = "invalid_toolchain_name_error_display")]
    InvalidToolchainName(String),
}

fn invalid_toolchain_name_error_description(_: &str) -> &str {
    "invalid toolchain name"
}

fn invalid_toolchain_name_error_display(f: &mut ::std::fmt::Formatter, t: &str) -> ::std::fmt::Result {
    write!(f, "invalid toolchain name: '{}'", t)
}

Notes

  • The ErrorKind must derive Debug
  • The ErrorKind must have pub visibility.
  • The ErrorKind must have a special Msg(String) member. Unlike error_chain! which adds this member implicitly, this macro requires it explicitly.
  • Doc comments and other attributes can be applied on the enum variants without any special syntax.
  • Rust will complain about using custom derives if you have #[macro_use] extern crate derive_error_chain; before #[macro_use] extern crate error_chain;. Instead, you will need to put the extern for derive_error_chain after the extern for error_chain

Enum attributes

  • #[error_chain(error = "ErrorName")]

    Override the name of the generated Error struct to the given name. If not provided, the struct will be named Error.

  • #[error_chain(result_ext = "ResultExtName")]

    Override the name of the generated ResultExt trait to the given name. If not provided, the trait will be named ResultExt.

  • #[error_chain(result = "ResultName")]

    Override the name of the generated Result type alias to the given name. If not provided, the alias will be named Result. If set to the empty string "", the alias will not be generated at all.

  • #[error_chain(backtrace = "false")] or #[error_chain(backtrace = false)]

    Disable backtrace functionality in the generated code. This should be kept in sync with the value of the backtrace feature of the error-chain crate. In other words, if you set backtrace = "false" here, you must also specify default-features = false for error-chain in your Cargo.toml

Variant definitions

  • Chainable links

    #[error_chain(link = "other_error::Error")]
    Another(other_error::ErrorKind),

    A chainable link is an error and errorkind that have been generated using error-chain or derive-error-chain. The variant must have a single field to hold the chained errorkind, and the link attribute must specify a path to the chained error.

  • Foreign links

    #[error_chain(foreign)]
    Fmt(::std::fmt::Error),

    A foreign link is an error that implements ::std::error::Error but otherwise does not follow error-chain's conventions. The variant must have a single field to hold the foreign error.

  • Custom links

    #[error_chain(custom)]
    InvalidToolchainName(String),

    A custom link is an arbitrary variant that can hold any members.

Variant attributes

In addition to the above attributes that identify the type of the variant's link, the below attributes can be used on all links.

  • #[error_chain(description = "some_function_expression")]

    Specifies a function expression to be used to implement ErrorKind::description(). This value is also returned from the implementation of ::std::error::Error::description() on the generated Error.

    The function expression can refer to a separate function:

        #[error_chain(description = "invalid_toolchain_name_error_description")]
        InvalidToolchainName(String),
    
    // <snip>
    
    fn invalid_toolchain_name_error_description(_: &str) -> &str {
        "invalid toolchain name"
    }

    or it can be an inline lambda wrapped in parentheses:

        #[error_chain(description = r#"(|_| "invalid toolchain name")"#)]
        InvalidToolchainName(String),

    The function expression must have the signature (...) -> &'static str. It should have one parameter for each field of the variant. The fields are passed in by reference.

    Thus in the above example, since InvalidToolchainName had a single field of type String, the function expression needed to be of type (&str) -> &'static str

    If not specified, the default implementation behaves in this way:

    • Chainable links: Forwards to the chained error kind's description()
    • Foreign links: Forwards to the foreign error's implementation of ::std::error::Error::description()
    • Custom links: Returns the stringified name of the variant.
  • #[error_chain(display = "some_function_expression")]

    Specifies a function expression to be used to implement ::std::fmt::Display::fmt() on the ErrorKind and generated Error

    This can be a separate function:

        #[error_chain(display = "invalid_toolchain_name_error_display")]
        InvalidToolchainName(String),
    
    // <snip>
    
    fn invalid_toolchain_name_error_display(f: &mut ::std::fmt::Formatter, t: &str) -> ::std::fmt::Result {
        write!(f, "invalid toolchain name: '{}'", t)
    }

    or an inline lambda wrapped in parentheses:

        #[error_chain(description = r#"(|f: &mut ::std::fmt::Formatter, t| write!(f, "invalid toolchain name: '{}'", t))"#)]
        InvalidToolchainName(String),

    The function expression must have the signature (&mut ::std::fmt::Formatter, ...) -> ::std::fmt::Result. It should have one &mut ::std::fmt::Formatter parameter, and one parameter for each field of the variant. The fields are passed in by reference.

    Thus in the above example, since InvalidToolchainName had a single field of type String, the function expression needed to be of type (&mut ::std::fmt::Formatter, &str) -> ::std::fmt::Result

    If not specified, the default implementation of ::std::fmt::Display::fmt() behaves in this way:

    • Chainable links: Forwards to the chained errorkind's implementation of ::std::fmt::Display::fmt()
    • Foreign links: Forwards to the foreign error's implementation of ::std::fmt::Display::fmt()
    • Custom links: Writes the description of the variant to the formatter.
  • #[error_chain(cause = "some_function_expression")]

    Specifies a function expression to be used to implement ::std::fmt::Error::cause() on the generated Error

    This can be a separate function:

        #[error_chain(cause = "parse_json_file_error_cause")]
        JSON(::std::path::PathBuf, ::serde_json::Error),
    
    // <snip>
    
    fn parse_json_file_error_cause<'a>(_: &::std::path::Path, err: &'a ::serde_json::Error) -> &'a ::std::error::Error {
        err
    }

    or an inline lambda wrapped in parentheses:

        #[error_chain(cause = "(|_, err| err)")]
           JSON(::std::path::PathBuf, ::serde_json::Error),

    The function expression must have the signature (...) -> &::std::error::Error. It should have one parameter for each field of the variant. The fields are passed in by reference. The result is wrapped in Option::Some() for returning from ::std::error::Error::cause()

    Thus in the above example, since JSON had two fields of type ::std::path::PathBuf and ::serde_json::Error, the function expression needed to be of type (&::std::path::Path, &::serde_json::Error) -> &::std::error::Error

    If not specified, the default implementation of ::std::error::Error::cause() behaves in this way:

    • Chainable links: Returns None
    • Foreign links: Forwards to the foreign error's implementation of ::std::error::Error::cause()
    • Custom links: Returns None

Functions

derive_error_chain