x1957
Posted on July 20, 2019
大家都建议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()))?;
💖 💪 🙅 🚩
x1957
Posted on July 20, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.