[−][src]Crate error_rules
Intro
Key feature of the error-rules crate is chained error handling without pain.
For example your application have nested modules: app -> garage -> car -> engine.
But how to know where this error happens?
Should be saved error context for each module.
To do that could be use .map_err() before each ? operator. But this way is too verbose.
The error-rules macro will do that automaticaly.
Idea is simple, each module has own error handler with configurable display text.
It pass source error wrapped into own error handler with custom display text.
So app will get error with text like: "Garage => Car => Engine => resource temporarily unavailable"
Declaring error types
Macro error_rules! implements Error, Result types and all necessary traits for Error.
All arguments should be comma-separated.
To prevent types shadowing all errors from standard library and other crates should be used
with module name. For example: io::Error.
Display format
Error display text defines in tuple after self => keyword.
First tuple argument is a format string. Additional arguments:
error- chained error textcontext- context for this error
use error_rules::*; error_rules! { self => ("app error => {}", error) } assert_eq!( Error::from("error message").to_string().as_str(), "app error => error message");
Error types
After display text you could define error types for conversions into Error chain.
By the default implements conversion for: &str, String
use std::io; use error_rules::*; error_rules! { self => ("app error => {}", error), std::io::Error, } let io_error = io::Error::new(io::ErrorKind::Other, "io-error"); assert_eq!( Error::from(io_error).to_string().as_str(), "app error => io-error");
Custom error types
Custom errors is an additional error kind to use with Error.
Defines like struct with display arguments after => keyword.
Could be defined without fields:
error_rules! { self => ("app error => {}", error), CustomError => ("custom error"), } assert_eq!( Error::from(CustomError).to_string().as_str(), "app error => custom error");
or with fields:
error_rules! { self => ("app error => {}", error), CustomError(usize) => ("custom error value:{}", 0), } assert_eq!( Error::from(CustomError(100)).to_string().as_str(), "app error => custom error value:100");
or with named fields:
error_rules! { self => ("app error => {}", error), CustomError { value: usize, } => ("custom error value:{}", value), } assert_eq!( Error::from(CustomError { value: 100 }).to_string().as_str(), "app error => custom error value:100");
Error context
Error context let to append additional information into error description.
For example will be useful to get know which file unavailable on File::open().
error_rules! { self => ("file reader ({}) => {}", context, error), std::io::Error, } let n = "not-found.txt"; let e = std::fs::File::open(n).context(n).unwrap_err(); assert_eq!( e.to_string().as_str(), "file reader (not-found.txt) => No such file or directory (os error 2)");
Macros
| bail | Exits a function and returns Error |
| ensure | Ensure that a boolean expression is true at runtime.
If condition is false then invokes |
| error_rules | Macro for chained error handling |