This crate uses macros 1.1 to derive custom errors.
Add this crate to your dependencies section:-
[dependencies]
derive-error = "0.0.4"
Import it in your main.rs
or lib.rs
:-
#[macro_use]
extern crate derive_error;
Deriving errors is simple. Simply create an enum for your errors as suggested in the Rust book, add short descriptions for the enum variants using doc comments, throw in a #[derive(Debug, Error)]
and you are done. Here is the example in the book implemented using this library:-
#[derive(Debug, Error)]
enum CliError {
/// IO Error
Io(io::Error),
/// Failed to parse the CSV file
Csv(csv::Error),
/// No matching cities with a population were found
NotFound,
}
This will derive implementations for Display
, Error
and From
. See the reql crate for a real world example of how to use this crate.
Not all errors are exactly the same and need, for example, From
implementations. derive-error supports attributes on Enum variants that allow you to enable/disable certain aspects of how Error deriving functions. There are 3 attributes that can be attached to variants of enums deriving Error
: non_std
, msg_embedded
, no_from
.
msg_embedded
displays the error through an item in the variant, generally a String
.
no_from
skips the From
impl for the variant of the enum, you want this if the error isn't coming from somewhere else, and your code is essentially the source of the error.
non_std
displays the error from the variant via it's doc comment ///
or it's embedded message (if the variant has that attribute), otherwise it will try and use the cause of the underlying error inside the variant. This is usually combined with no_from
.
#[derive(Debug, Error)]
enum Error {
#[error(msg_embedded, no_from, non_std)]
RuntimeError(String),
Io(Io::Error),
#[error(non_std, no_from)]
Json(serde_json::Value)
}
This example showcases how to attach the attributes. RuntimeError
has a String
internally which in the case of an error will be used for displaying. Io
is getting a From
implementation for Io::Error
and this is generally the most common usecase. It is also possible to embed values directly in errors, in the Json
variant it's embedding a Value
inside, to be used later on for other information.
These were adapted from the the reql crate's usage of derive-error