如何处理 rust 上的盒装和链式错误?
How to deal with boxed and chained error on rust?
我有很多代理 uri(http 和 socks5),我正在使用 reqwest 通过这些代理发送一些 http 请求,如果他不工作我想放弃代理。
for proxy in proxies {
let proxy = match Proxy::all(proxy_url) {
Ok(proxy) => proxy,
Err(e) => {
eprintln!("creating proxy failed! {:?}", e);
continue;
}
};
let client = match Client::builder()
.proxy(proxy)
.build()
let client = match client {
Ok(client) => client,
Err(e) => {
eprintln!("building client failed! {:?}", e);
continue;
}
}
loop {
match client.get(&config.endpoint).send().await {
Ok(_) => {}
Err(e) => {
if e.is_proxy_error() { // this method doesn't exist
eprintln!("Dropping proxy...");
break;
} else {
eprintln!("client error! {:?}", e);
}
}
}
}
}
而且我有很多种Reqwest::Error
reqwest::Error { kind: Request, url: "http://example.com/", source: hyper::Error(Connect, "socks connect error: Invalid response version") }
reqwest::Error { kind: Request, url: "http://example.com/", source: hyper::Error(Connect, "socks connect error: Proxy server unreachable") }
reqwest::Error { kind: Request, url: "http://example.com/", source: hyper::Error(Connect, "socks connect error: Connection refused") }
reqwest::Error { kind: Request, url: "http://example.com/", source: hyper::Error(Connect, "socks connect error: Connection reset by peer (os error 104)") }
在大多数情况下,错误消息是明确的,但我如何以不同的方式处理它们中的每一个?
reqwest::Error
有 inner
字段,这是私有的,所以我无法访问他。
如果我得到 reqwest::Error
的来源,我只有一个 Box<syn Error>
,我不能像对待 hyper::Error
您可以将 Error::source()
的结果向下转换为具体的错误类型,例如
use std::error::Error;
...
Err(reqwest_error) => {
let hyper_error: Option<&hyper::Error> = reqwest_error
.source()
.unwrap()
.downcast_ref();
...
}
此代码使用 unwrap()
从 source()
返回的 Option
中提取错误。如果你不能保证错误总是有一个来源,你应该使用一些有条件的方式来解包来源,例如
let hyper_error: Option<&hyper::Error> = reqwest_error
.source()
.and_then(|e| e.downcast_ref());
我有很多代理 uri(http 和 socks5),我正在使用 reqwest 通过这些代理发送一些 http 请求,如果他不工作我想放弃代理。
for proxy in proxies {
let proxy = match Proxy::all(proxy_url) {
Ok(proxy) => proxy,
Err(e) => {
eprintln!("creating proxy failed! {:?}", e);
continue;
}
};
let client = match Client::builder()
.proxy(proxy)
.build()
let client = match client {
Ok(client) => client,
Err(e) => {
eprintln!("building client failed! {:?}", e);
continue;
}
}
loop {
match client.get(&config.endpoint).send().await {
Ok(_) => {}
Err(e) => {
if e.is_proxy_error() { // this method doesn't exist
eprintln!("Dropping proxy...");
break;
} else {
eprintln!("client error! {:?}", e);
}
}
}
}
}
而且我有很多种Reqwest::Error
reqwest::Error { kind: Request, url: "http://example.com/", source: hyper::Error(Connect, "socks connect error: Invalid response version") }
reqwest::Error { kind: Request, url: "http://example.com/", source: hyper::Error(Connect, "socks connect error: Proxy server unreachable") }
reqwest::Error { kind: Request, url: "http://example.com/", source: hyper::Error(Connect, "socks connect error: Connection refused") }
reqwest::Error { kind: Request, url: "http://example.com/", source: hyper::Error(Connect, "socks connect error: Connection reset by peer (os error 104)") }
在大多数情况下,错误消息是明确的,但我如何以不同的方式处理它们中的每一个?
reqwest::Error
有 inner
字段,这是私有的,所以我无法访问他。
如果我得到 reqwest::Error
的来源,我只有一个 Box<syn Error>
,我不能像对待 hyper::Error
您可以将 Error::source()
的结果向下转换为具体的错误类型,例如
use std::error::Error;
...
Err(reqwest_error) => {
let hyper_error: Option<&hyper::Error> = reqwest_error
.source()
.unwrap()
.downcast_ref();
...
}
此代码使用 unwrap()
从 source()
返回的 Option
中提取错误。如果你不能保证错误总是有一个来源,你应该使用一些有条件的方式来解包来源,例如
let hyper_error: Option<&hyper::Error> = reqwest_error
.source()
.and_then(|e| e.downcast_ref());