diff --git a/ylong_http_client/src/async_impl/conn/http1.rs b/ylong_http_client/src/async_impl/conn/http1.rs index fd74173dca8853c006883f0ef7f3ad783b743d51..49e588841ace495b5422c1839d8402ed0da835cd 100644 --- a/ylong_http_client/src/async_impl/conn/http1.rs +++ b/ylong_http_client/src/async_impl/conn/http1.rs @@ -194,7 +194,14 @@ where Ok(size) => written += size, Err(e) => { conn.shutdown(); - return err_from_other!(BodyTransfer, e); + + let error = e.into(); + // When using `Uploader`, here we can get `UserAborted` error. + return if error.source().is_some() { + Err(HttpClientError::user_aborted()) + } else { + err_from_other!(BodyTransfer, error) + }; } } } diff --git a/ylong_http_client/src/error.rs b/ylong_http_client/src/error.rs index c786abee870350840102eed837d6911518df13a3..cf4dcd096ed2f009ac9a9a2a61a980d7ba59fc86 100644 --- a/ylong_http_client/src/error.rs +++ b/ylong_http_client/src/error.rs @@ -15,6 +15,7 @@ //! this crate. use core::fmt::{Debug, Display, Formatter}; +use std::sync::Once; use std::{error, io}; /// The structure encapsulates errors that can be encountered when working with @@ -148,7 +149,21 @@ impl Display for HttpClientError { } } -impl error::Error for HttpClientError {} +impl error::Error for HttpClientError { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + static mut USER_ABORTED: Option> = None; + static ONCE: Once = Once::new(); + + ONCE.call_once(|| { + unsafe { USER_ABORTED = Some(Box::new(HttpClientError::user_aborted())) }; + }); + + if self.kind == ErrorKind::UserAborted { + return unsafe { USER_ABORTED.as_ref().map(|e| e.as_ref()) }; + } + None + } +} /// Error kinds which can indicate the type of a `HttpClientError`. #[derive(Debug, Clone, Copy, PartialEq, Eq)]