Skip to content

Commit

Permalink
fix(client): don't panic in DNS resolution when task cancelled (#2229)
Browse files Browse the repository at this point in the history
If the runtime is dropped while a DNS request is being made, it can
lead to a panic. This patch checks if the task was cancelled, and
returns a generic IO error instead of panicking in that case.

The following code reproduces the problem on my macOS machine:

```
use hyper::Client;
use tokio::runtime;

type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;

fn main() {
    let rt = runtime::Builder::new()
        .threaded_scheduler()
        .core_threads(1)
        .enable_all()
        .build()
        .unwrap();

    // spawn a request and then drop the runtime immediately
    rt.spawn(fetch_url());
}

async fn fetch_url() -> Result<()> {
    let url: hyper::Uri = "http://example.com".parse()?;
    let client = Client::builder().build_http::<hyper::Body>();

    let res = client.get(url).await?;
    println!("Response: {}", res.status());

    Ok(())
}
```
  • Loading branch information
dae authored Jun 11, 2020
1 parent 9998f0f commit 0d0d363
Showing 1 changed file with 7 additions and 1 deletion.
8 changes: 7 additions & 1 deletion src/client/connect/dns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,13 @@ impl Future for GaiFuture {
Pin::new(&mut self.inner).poll(cx).map(|res| match res {
Ok(Ok(addrs)) => Ok(GaiAddrs { inner: addrs }),
Ok(Err(err)) => Err(err),
Err(join_err) => panic!("gai background task failed: {:?}", join_err),
Err(join_err) => {
if join_err.is_cancelled() {
Err(io::Error::new(io::ErrorKind::Interrupted, join_err))
} else {
panic!("gai background task failed: {:?}", join_err)
}
}
})
}
}
Expand Down

0 comments on commit 0d0d363

Please sign in to comment.