http-rs / surf

Fast and friendly HTTP client framework for async Rust
https://docs.rs/surf
Apache License 2.0
1.47k stars 120 forks source link

The error type does not always work with ? #158

Open ghost opened 4 years ago

ghost commented 4 years ago

Example:

async fn fetch(url: String, sender: Sender<String>) -> anyhow::Result<()> {
    let body = surf::get(&url).recv_string().await?;
    sender.send(body).await;
    Ok(())
}

Error:

  |
9 |     let body = surf::get(&url).recv_string().await?;
  |                                                   ^ doesn't have a size known at compile-time
  |
  = help: the trait `std::marker::Sized` is not implemented for `dyn std::error::Error + std::marker::Send + std::marker::Sync`
  = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
  = note: required because of the requirements on the impl of `std::error::Error` for `std::boxed::Box<dyn std::error::Error + std::marker::Send + std::marker::Sync>`
  = note: required because of the requirements on the impl of `std::convert::From<std::boxed::Box<dyn std::error::Error + std::marker::Send + std::marker::Sync>>` for `anyhow::Error`
  = note: required by `std::convert::From::from`

Workaround:

async fn fetch(url: String, sender: Sender<String>) -> anyhow::Result<()> {
    let body = surf::get(&url)
        .recv_string()
        .await
        .map_err(|e| anyhow!(e))?;
    sender.send(body).await;
    Ok(())
}

I think the proper solution is for the error type (Exception) to be a dedicated type that implements std::error::Error.

abreis commented 4 years ago

See #86 for some previous discussion on this issue.