rust `?`无法将错误转换为`std::io::Error`

uinbv5nw  于 2023-08-05  发布在  其他
关注(0)|答案(2)|浏览(97)

我试图使用reqwest库和以下模式做一篇文章,我在网上的各个地方找到了:

let res = http_client.post(&url)
                          .header("Content-Type", "application/x-www-form-urlencoded")
                          .form(&form_data)
                          .send()
                          .await?;
println!("authenticate response: {}", res.status)

字符串
上面的代码块导致编译错误:

`?` couldn't convert the error to `std::io::Error` the trait ` 
      `std::convert::From<reqwest::error::Error>` is not implemented for `std::io::Error`


我不明白为什么我得到这个错误。我的代码尽可能接近示例。如果我删除?res.status,它将编译。但是我需要得到状态res.status的值。更重要的是,我需要了解我错过了什么或做错了什么。

wvmv3b1j

wvmv3b1j1#

您的错误是由调用此块的函数的返回类型引起的,编译器希望返回std::io::Error类型的错误。
从错误描述中,我得出的结论是main函数看起来像这样:

fn main() -> Result<(), std::io::Error> {
    // ...
}

字符串
问题是reqwest不返回io::Error。这是我几个月前写的一段文字:

use exitfailure::ExitFailure;

fn main() -> Result<(), ExitFailure> {
    let res = http_client
        .post(&url)
        .header("Content-Type", "application/x-www-form-urlencoded")
        .form(&form_data)
        .send()
        .await?;

    println!("authenticate response: {}", res.status);
    Ok(())
}


我使用exitfailure将返回的错误类型转换为main的可读返回类型。我想这也会解决你的问题。

  • 更新:* 在评论中指出,exifail已经弃用了依赖项,这可以在没有外部crate的情况下实现。返回封装的动态错误的推荐方法是:Box<dyn std::error::Error>
fn main() -> Result<(), Box<dyn std::error::Error>> {
    let res = http_client
        .post(&url)
        .header("Content-Type", "application/x-www-form-urlencoded")
        .form(&form_data)
        .send()
        .await?;

    println!("authenticate response: {}", res.status);
    Ok(())

}


从我所看到的main返回agreageted错误的行为是相同的。

uajslkp6

uajslkp62#

map_err用于转换Rust中的错误类型。它的闭包从Result错误中取出错误并将其转换为新的错误。如果您在项目中使用并将鼠标悬停在它上面,您会看到以下内容
将Result<T,E>Map到Result<T,F>,方法是将一个函数应用到包含的Err值,而不改变Ok值。
此函数可用于在处理错误时传递成功结果。

use std::io::{Error,ErrorKind};

let res = http_client.post(&url)
                          .header("Content-Type", "application/x-www-form-urlencoded")
                          .form(&form_data)
                          .send()
                          .await; // removed ?
                          // ErrorKind is enum. you could choose different options
                          .map_err(|err|Error::new(ErrorKind::Other,"could not do post req"))?;

字符串

相关问题