Macro custom_error::custom_error
source · macro_rules! custom_error {
(pub $($tt:tt)*) => { ... };
(
$( ($prefix:tt) )* // `pub` marker
$errtype:ident // Name of the error type to generate
$( < $(
$type_param:ident // Optional type parameters for generic error types
),*
> )*
$(
$field:ident // Name of an error variant
$( { $(
$attr_name:ident // Name of an attribute of the error variant
:
$attr_type:ty // type of the attribute
),* } )*
=
$( @{ $($msg_fun:tt)* } )*
$($msg:expr)* // The human-readable error message
),*
$(,)* // Trailing comma
) => { ... };
}
Expand description
Constructs a custom error type.
Examples
Simple error
use custom_error::custom_error;
custom_error!{ pub MyError
Bad = "Something bad happened",
Terrible = "This is a very serious error!!!"
}
assert_eq!("Something bad happened", MyError::Bad.to_string());
assert_eq!("This is a very serious error!!!", MyError::Terrible.to_string());
Custom error with parameters
use custom_error::custom_error;
custom_error!{SantaError
BadChild{name:String, foolishness:u8} = "{name} has been bad {foolishness} times this year",
TooFar = "The location you indicated is too far from the north pole",
InvalidReindeer{legs:u8} = "The reindeer has {legs} legs"
}
assert_eq!(
"Thomas has been bad 108 times this year",
SantaError::BadChild{
name: "Thomas".into(),
foolishness: 108
}.to_string());
assert_eq!(
"The location you indicated is too far from the north pole",
SantaError::TooFar.to_string()
);
assert_eq!(
"The reindeer has 8 legs",
SantaError::InvalidReindeer{legs:8}.to_string()
);
Automatic conversion from other error types
You can add a special field named source
to your error types.
Use this field to include the lower-level source of the error.
It will be used in the error
source()
method, and automatic conversion from the source error type to your custom error type will be possible
(your error type will implement From<SourceErrorType>
).
limitations
- You cannot have several error cases that contain a single source field of the same type:
custom_error!(E A{source:X} B{source:Y})
is allowed, butcustom_error!(E A{source:X} B{source:X})
is forbidden. - If the source field is not the only one, then the automatic conversion will not be implemented.
use custom_error::custom_error;
use std::{io, io::Read, fs::File, result::Result};
custom_error!{MyError
IO{source: io::Error} = "input/output error",
Unknown = "unknown error"
}
fn read_file(filename: &str) -> Result<String, MyError> {
let mut res = String::new();
File::open(filename)?.read_to_string(&mut res)?;
Ok(res)
}
assert_eq!(
"input/output error",
read_file("/i'm not a file/").unwrap_err().to_string()
)
Custom formatting function for error messages
If the format string syntax is not enough to express your complex error formatting needs, you can use custom code to generate your error description.
use custom_error::custom_error;
static lang : &'static str = "FR";
custom_error!{ pub MyError
Problem = @{ localize(lang, "A problem occurred") },
}
assert_eq!("Un problème est survenu", MyError::Problem.to_string());
use custom_error::custom_error;
use std::io::Error;
use std::io::ErrorKind::*;
custom_error!{ pub MyError
Io{source: Error} = @{
match source.kind() {
NotFound => "The file does not exist",
TimedOut => "The operation timed out",
_ => "unknown error",
}
},
}
assert_eq!("The operation timed out", MyError::Io{source: TimedOut.into()}.to_string());