From 0d0d3635476ba22e5a2b39b0e4b243f57f1f36d2 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Fri, 12 Jun 2020 06:36:17 +1000 Subject: [PATCH] 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 = std::result::Result>; 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::(); let res = client.get(url).await?; println!("Response: {}", res.status()); Ok(()) } ``` --- src/client/connect/dns.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/client/connect/dns.rs b/src/client/connect/dns.rs index acffb8b9..61357917 100644 --- a/src/client/connect/dns.rs +++ b/src/client/connect/dns.rs @@ -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) + } + } }) } }