loading...

Rust failure

x1957 profile image x1957 ・1 min read

大家都建议error handling用failure这个库,看了看(:

先贴代码

use failure::{Error, Fail};
use reqwest;

#[derive(Fail, Debug)]
enum MyError {
    #[fail(display = "filed {} not exist", _0)]
    FileNotExist(String),
    // #[fail(display = "http error: {}", _0)]
    // HttpError(#[fail(cause)] reqwest::Error),
}

fn http_get(url: Option<String>) -> std::result::Result<(), Error> {
    if url == None {
        // just test
        return Err(MyError::FileNotExist("url".to_string()).into());
    }
    let client = reqwest::Client::new();
    let result = client.get(&url.unwrap()).send()?.text()?;
    println!("{}", result);
    Ok(())
}

fn main() {
    http_get(Some("https://www.baidu.com".to_string())).unwrap();
}

我们可以用failure::Error来替换掉std::error::Error,我们自己的error呢就去实现Fail这个trait,这里我们用了他的过程宏,让它给我们默认实现了,可以cargo expand展开看下

#[allow(non_upper_case_globals)]
#[doc(hidden)]
const _DERIVE_failure_Fail_FOR_MyError: () = {
    impl ::failure::Fail for MyError {
        fn name(&self) -> Option<&str> {
            Some("fail::MyError")
        }
        #[allow(unreachable_code)]
        fn cause(&self) -> ::failure::_core::option::Option<&dyn ::failure::Fail> {
            match *self {
                MyError::FileNotExist(ref __binding_0) => return None,
            }
            None
        }
        #[allow(unreachable_code)]
        fn backtrace(&self) -> ::failure::_core::option::Option<&::failure::Backtrace> {
            match *self {
                MyError::FileNotExist(ref __binding_0) => return None,
            }
            None
        }
    }
};

其实遇到的最大的问题不是这个,而是,我

return Err(MyError::FileNotExist("url".to_string()));

的时候要报错说要的是failure::failure::Error而我返回的是这个我自定义的Error,但是不是说好的是实现了Fail接口就行吗?文档也没写,又来在某个issue里面发现,说要么into(),要么?

所以得写成

return Err(MyError::FileNotExist("url".to_string()).into());

或者

Err(MyError::FileNotExist("url".to_string()))?;

Posted on by:

Discussion

pic
Editor guide