mirror of
https://github.com/haraldh/chainerror.git
synced 2025-05-29 21:18:07 +02:00
macro hygiene
This commit is contained in:
parent
a558c35ba4
commit
ae6c01aab2
6 changed files with 372 additions and 68 deletions
|
@ -1,8 +1,9 @@
|
|||
use chainerror::*;
|
||||
use std::error::Error;
|
||||
use std::io;
|
||||
use std::result::Result;
|
||||
|
||||
use chainerror::*;
|
||||
|
||||
fn do_some_io() -> Result<(), Box<Error + Send + Sync>> {
|
||||
Err(io::Error::from(io::ErrorKind::NotFound))?;
|
||||
Ok(())
|
||||
|
|
|
@ -15,7 +15,7 @@ pub mod mycrate {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ErrorKind {
|
||||
Func2,
|
||||
IO(String),
|
||||
|
@ -42,7 +42,7 @@ pub mod mycrate {
|
|||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Box<std::error::Error>> {
|
||||
fn main() -> Result<(), Box<std::error::Error + Send + Sync>> {
|
||||
use mycrate::func1;
|
||||
use mycrate::ErrorKind;
|
||||
use std::error::Error;
|
||||
|
|
|
@ -182,7 +182,7 @@ pub mod mycrate {
|
|||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Box<std::error::Error>> {
|
||||
fn main() -> Result<(), Box<std::error::Error + Send + Sync>> {
|
||||
use mycrate::func1;
|
||||
use mycrate::ErrorKind;
|
||||
use std::error::Error;
|
||||
|
|
139
examples/tutorial15.rs
Normal file
139
examples/tutorial15.rs
Normal file
|
@ -0,0 +1,139 @@
|
|||
pub mod mycrate {
|
||||
use std::io;
|
||||
|
||||
use chainerror::*;
|
||||
|
||||
fn do_some_io(_f: &str) -> std::result::Result<(), io::Error> {
|
||||
Err(io::Error::from(io::ErrorKind::NotFound))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
derive_str_cherr!(Func2Error);
|
||||
|
||||
fn func2() -> std::result::Result<(), Box<std::error::Error + Send + Sync>> {
|
||||
let filename = "foo.txt";
|
||||
do_some_io(filename)
|
||||
.map_err(|e| cherr!(e, Func2Error(format!("Error reading '{}'", filename))))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ErrorKind {
|
||||
Func2,
|
||||
IO(String),
|
||||
FatalError(String),
|
||||
Unknown,
|
||||
}
|
||||
|
||||
derive_err_kind!(Error, ErrorKind);
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
impl std::fmt::Display for ErrorKind {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
ErrorKind::FatalError(e) => write!(f, "fatal error {}", e),
|
||||
ErrorKind::Unknown => write!(f, "unknown error"),
|
||||
ErrorKind::Func2 => write!(f, "func1 error calling func2"),
|
||||
ErrorKind::IO(filename) => write!(f, "Error reading '{}'", filename),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ErrorKind {
|
||||
fn from_io_error(e: &io::Error, f: String) -> Self {
|
||||
match e.kind() {
|
||||
io::ErrorKind::BrokenPipe => panic!("Should not happen"),
|
||||
io::ErrorKind::ConnectionReset => {
|
||||
ErrorKind::FatalError(format!("While reading `{}`: {}", f, e))
|
||||
}
|
||||
_ => ErrorKind::IO(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&(dyn std::error::Error + 'static + Send + Sync)> for ErrorKind {
|
||||
fn from(e: &(dyn std::error::Error + 'static + Send + Sync)) -> Self {
|
||||
if let Some(_) = e.downcast_ref::<io::Error>() {
|
||||
ErrorKind::IO(String::from("Unknown filename"))
|
||||
} else if let Some(_) = e.downcast_inner_ref::<Func2Error>() {
|
||||
ErrorKind::Func2
|
||||
} else {
|
||||
ErrorKind::Unknown
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&std::boxed::Box<dyn std::error::Error + 'static + Send + Sync>> for ErrorKind {
|
||||
fn from(e: &std::boxed::Box<dyn std::error::Error + 'static + Send + Sync>) -> Self {
|
||||
Self::from(&**e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Func2Error> for ErrorKind {
|
||||
fn from(_: &Func2Error) -> Self {
|
||||
ErrorKind::Func2
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&io::Error> for ErrorKind {
|
||||
fn from(e: &io::Error) -> Self {
|
||||
ErrorKind::IO(format!("{}", e))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn func1() -> Result<()> {
|
||||
func2().map_err(|e| cherr!(e, ErrorKind::from(&e)))?;
|
||||
|
||||
let filename = "bar.txt";
|
||||
|
||||
do_some_io(filename)
|
||||
.map_err(|e| cherr!(e, ErrorKind::from_io_error(&e, filename.into())))?;
|
||||
do_some_io(filename).map_err(|e| cherr!(e, ErrorKind::IO(filename.into())))?;
|
||||
do_some_io(filename).map_err(|e| cherr!(e, ErrorKind::from(&e)))?;
|
||||
do_some_io(filename).map_err(minto_cherr!(ErrorKind))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn super_func1() -> Result<()> {
|
||||
func1().map_err(minto_cherr!(ErrorKind))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Box<std::error::Error + Send + Sync>> {
|
||||
use mycrate::super_func1;
|
||||
use mycrate::ErrorKind;
|
||||
use std::error::Error;
|
||||
use std::io;
|
||||
|
||||
if let Err(e) = super_func1() {
|
||||
match e.kind() {
|
||||
ErrorKind::FatalError(f) => eprintln!("Main Error Report: Fatal Error: {}", f),
|
||||
ErrorKind::Unknown => eprintln!("Main Error Report: Unknown error occurred"),
|
||||
ErrorKind::Func2 => eprintln!("Main Error Report: func1 error calling func2"),
|
||||
ErrorKind::IO(ref filename) => {
|
||||
eprintln!("Main Error Report: func1 error reading '{}'", filename)
|
||||
}
|
||||
}
|
||||
|
||||
eprintln!();
|
||||
let mut s: &Error = &e;
|
||||
while let Some(c) = s.source() {
|
||||
if let Some(ioerror) = c.downcast_ref::<io::Error>() {
|
||||
eprintln!("caused by: std::io::Error: {}", ioerror);
|
||||
match ioerror.kind() {
|
||||
io::ErrorKind::NotFound => eprintln!("of kind: std::io::ErrorKind::NotFound"),
|
||||
_ => {}
|
||||
}
|
||||
} else {
|
||||
eprintln!("caused by: {}", c);
|
||||
}
|
||||
s = c;
|
||||
}
|
||||
|
||||
eprintln!("\nDebug Error:\n{:?}", e);
|
||||
}
|
||||
Ok(())
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue