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

`?` couldn't convert the error to `std::io::Error`

我正在尝试 post 使用 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 值。更重要的是,我需要了解我遗漏了什么或做错了什么。

您的错误是由您调用此块的函数的 return 类型引起的,编译器希望 return 类型为 std::io::Error.[=20 的错误=]

根据错误描述,我得出的结论是您的 main 函数看起来像这样:

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

问题是 reqwest 没有 return 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 将 returned 错误类型转换为人类可读的 return 类型 main。我想它也能解决你的问题。

更新: 在评论中指出,exifailure 已经弃用了依赖项,这可以在没有外部板条箱的情况下实现。有一种 returning 封装动态错误的推荐方法: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(())

}

据我所知,returning 来自 main 的约定错误的行为是相同的。