Custom error types with the failure crate

The preceding parsing needs its own error type to cover both errors—incorrect parsing of numbers, and invalid variants. Let's declare the ColorError type in this section.

Error handling in Rust is particularly easy. There's a Result type that wraps successful and unsuccessful outcomes in a single entity. Result interprets any type as an error type and you can transform one result to another using the try! macro or the ? operator. Joining different error types, however, is much more complicated. There's the std::error::Error trait, which provides a generic interface for all errors, but it's a little clumsy. To create errors in a more user-friendly way, you can use the failure crate.

This crate helps with error handling and contains extensive failure::Error types, which are compatible with other errors that implement the std::Error::Error trait. You can convert any error type that implements this trait to a generic failure::Error. This crate also includes macros that can be used to derive your own error type and the failure::Fail trait to implement extra features, such as Backtrace, which provides extra information about the primary cause of an error at runtime.

Declare this type in the color.rs file:

#[derive(Debug, Fail)]
pub enum ColorError {
#[fail(display = "parse color's component error: {}", _0)]
InvalidComponent(#[cause] ParseIntError),
#[fail(display = "invalid value: {}", value)]
InvalidValue {
value: String,
},
}

The ColorError enumeration has two variants: InvalidComponent for parsing issues and InvalidValue if the wrong value is provided. To implement the necessary error traits for this type, we derive the Fail trait with the #[derive(Debug, Fail)] attribute. The Debug trait implementation is also necessary for Fail deriving.

To create error messages, we added the fail attribute with a display parameter that expects a message with parameters to interpolate into a format string. For fields, you can use names, such as value, and numbers with the underscore prefix to indicate their field position. To insert the first field, for example, use the name _0. To mark a field as a nested error, use the #[cause] attribute.

Deriving the Fail trait won't implement From for types that we used as variants of the ColorError enum. You should do this yourself:

impl From<ParseIntError> for ColorError {
fn from(err: ParseIntError) -> Self {
ColorError::InvalidComponent(err)
}
}

The ColorError type is now ready to use with the ? operator, and we can add random color generation to our microservice, together with the shuffling of a binary array.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.129.210.91