fix(client): don't panic in DNS resolution when task cancelled (#2229)
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(())
}
```
This commit is contained in:
@@ -141,7 +141,13 @@ impl Future for GaiFuture {
|
|||||||
Pin::new(&mut self.inner).poll(cx).map(|res| match res {
|
Pin::new(&mut self.inner).poll(cx).map(|res| match res {
|
||||||
Ok(Ok(addrs)) => Ok(GaiAddrs { inner: addrs }),
|
Ok(Ok(addrs)) => Ok(GaiAddrs { inner: addrs }),
|
||||||
Ok(Err(err)) => Err(err),
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user