eyre-rs / color-eyre

Custom hooks for colorful human oriented error reports via panics and the eyre crate
Other
958 stars 57 forks source link

Is there an easy way to make custom errors have equivalent report functions #133

Closed BppleMan closed 1 year ago

BppleMan commented 1 year ago

Is there some trait that allows me to obtain the reporter's ability after implementation?

I defined an enum error with thiserrror:

#[derive(Debug, Error)]
pub enum MyError {
    #[error(transparent)]
    IoError(#[from] std::io::Error),
    #[error("{0}")]
    MyPanic(String),
    #[error("{0}")]
    OtherPanic(String),
}

fn fun1() -> color_eyre::Result<(), MyError> {
    if condition {
        Err(MyError::MyPanic(""))
    } else {
        Err(MyError::OtherPanic(""))
    }
}

fn fun2() -> color_eyre::Result<(), MyError> {
    fun1()
}

fn fun3() -> color_eyre::Result<(), MyError> {
    match fun1() {
        Ok(_) => {},
        Err(e) => {
            match e {
                MyError::MyPanic(s) => { /* do sth */ },
                MyError::OtherPanic(_) => Err(e),
            }
        }
    }
}
BppleMan commented 1 year ago

If anyone needs to get any fields or function calls from the original error, they can use downcast_ref

fn fun1(condition: bool) -> color_eyre::Result<(), Report> {
    if condition {
        Err(MyError::MyPanic("this is MyPanic".to_string()).into())
    } else {
        Err(MyError::OtherPanic("this is OtherPanic".to_string()).into())
    }
}

fn fun2() -> color_eyre::Result<()> {
    fun1(true)
}

fn fun3(condition: bool) -> color_eyre::Result<()> {
    match fun1(condition) {
        Ok(_) => Ok(()),
        Err(e) => {
            match e.downcast_ref().unwrap() {
                MyError::MyPanic(s) => {
                    println!("MyPanic: {:#?} is catched. then will return Ok", &e);
                    Ok(())
                },
                _ => {
                    println!("not catched");
                    Err(e)
                },
            }
        }
    }
}