我正在尝试通过HTTP实现std::io::Write
,而我不确定如何处理std::io::ErrorKind
中没有对应项的错误。
这是一个简短的复制品:
extern crate reqwest;
use std::io::Write;
use std::io::Result;
struct HttpClient {
// Some configurations (compression, certificates, timeouts)
}
impl Write for HttpClient {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
let client = ::reqwest::Client::builder().build()?;
let res = client.post("http://httpbin.org/post").body(buf).send()?;
Ok(buf.len())
}
fn flush(&mut self) -> Result<()> {
Ok(())
}
}
编译器响应2个错误:
error[E0277]: the trait bound `std::io::Error: std::convert::From<reqwest::Error>` is not satisfied
--> src/main.rs:12:22
|
12 | let client = ::reqwest::Client::builder().build()?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From<reqwest::Error>` is not implemented for `std::io::Error`
|
= help: the following implementations were found:
<std::io::Error as std::convert::From<std::io::ErrorKind>>
<std::io::Error as std::convert::From<std::ffi::NulError>>
<std::io::Error as std::convert::From<std::io::IntoInnerError<W>>>
<std::io::Error as std::convert::From<serde_json::error::Error>>
<std::io::Error as std::convert::From<openssl::error::ErrorStack>>
= note: required by `std::convert::From::from`
error[E0277]: the trait bound `std::io::Error: std::convert::From<reqwest::Error>` is not satisfied
--> src/main.rs:13:19
|
13 | let res = client.post("http://httpbin.org/post").body(buf).send()?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From<reqwest::Error>` is not implemented for `std::io::Error`
|
= help: the following implementations were found:
<std::io::Error as std::convert::From<std::io::ErrorKind>>
<std::io::Error as std::convert::From<std::ffi::NulError>>
<std::io::Error as std::convert::From<std::io::IntoInnerError<W>>>
<std::io::Error as std::convert::From<serde_json::error::Error>>
<std::io::Error as std::convert::From<openssl::error::ErrorStack>>
= note: required by `std::convert::From::from`
我可以做几件事,但我对其中任何一件都不满意:
使用map_err
将reqwest::Error
映射到std::io::Error
- 这并不总是微不足道的。例如,我如何映射TooManyRedirects
?我可以使用std::io::ErrorKind::Other
,但感觉不对。
定义我自己的错误类型MyError
,并为std::convert::From
至reqwest::Error
以及MyError
至MyError
实施std::io::Error
- 此从以前提出同样的担忧 - 并非所有错误都可以轻易兑换。
这里还有其他更好的选择吗?
答案 0 :(得分:1)
使用io::Error
是您可以执行的唯一事情,因为这是特征所需的合同。其他一切都归结为细节和人体工程学。
io::Error::new
接受io::ErrorKind
和可以转换为error::Error
的内容。
我可能会编写一个函数,通过调用io::Error
将您的域错误转换为io::Error::new
,然后在map_err
处使用此新函数。我首先将所有内容都塞进ErrorKind::Other
,直到找到一个特定的Reqwest错误应该是其他原因的原因。
您的消费者是否真的关心某些特别是重定向过多的内容?通过构造,答案必须为“否”,因为它们可能在File
或TcpSocket
上运行,两者都没有这样的概念。
我不相信在这种情况下我会创建一个包装错误类型;我看不出它会如何提供任何价值。它需要额外的类型注释,你可以通过函数“免费”获得。
这并非总是微不足道。
这是正确的 - 将两个截然不同的部分胶合在一起有时并不完全符合我们想要的方式。这是使编程既令人兴奋又可怕的部分原因。