From 740654e55d2bb2f50709f20fb4054a5504d8c2fb Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Fri, 11 Mar 2022 17:44:06 -0800 Subject: [PATCH] refactor(error): improve error message when user body ends early --- src/error.rs | 10 +++++----- src/proto/h1/conn.rs | 6 ++---- src/proto/h1/encode.rs | 12 ++++++++++-- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/error.rs b/src/error.rs index 265f9172dc..20acf3a7a5 100644 --- a/src/error.rs +++ b/src/error.rs @@ -53,8 +53,6 @@ pub(super) enum Kind { /// Error while writing a body to connection. #[cfg(any(feature = "http1", feature = "http2"))] BodyWrite, - /// The body write was aborted. - BodyWriteAborted, /// Error calling AsyncWrite::shutdown() #[cfg(feature = "http1")] Shutdown, @@ -96,6 +94,8 @@ pub(super) enum User { /// Error calling user's HttpBody::poll_data(). #[cfg(any(feature = "http1", feature = "http2"))] Body, + /// The user aborted writing of the outgoing body. + BodyWriteAborted, /// Error calling user's MakeService. #[cfg(any(feature = "http1", feature = "http2"))] #[cfg(feature = "server")] @@ -193,7 +193,7 @@ impl Error { /// Returns true if the body write was aborted. pub fn is_body_write_aborted(&self) -> bool { - matches!(self.inner.kind, Kind::BodyWriteAborted) + matches!(self.inner.kind, Kind::User(User::BodyWriteAborted)) } /// Returns true if the error was caused by a timeout. @@ -305,7 +305,7 @@ impl Error { } pub(super) fn new_body_write_aborted() -> Error { - Error::new(Kind::BodyWriteAborted) + Error::new(Kind::User(User::BodyWriteAborted)) } fn new_user(user: User) -> Error { @@ -444,7 +444,6 @@ impl Error { Kind::Body => "error reading a body from connection", #[cfg(any(feature = "http1", feature = "http2"))] Kind::BodyWrite => "error writing a body to connection", - Kind::BodyWriteAborted => "body write aborted", #[cfg(feature = "http1")] Kind::Shutdown => "error shutting down connection", #[cfg(feature = "http2")] @@ -454,6 +453,7 @@ impl Error { #[cfg(any(feature = "http1", feature = "http2"))] Kind::User(User::Body) => "error from user's HttpBody stream", + Kind::User(User::BodyWriteAborted) => "user body write aborted", #[cfg(any(feature = "http1", feature = "http2"))] #[cfg(feature = "server")] Kind::User(User::MakeService) => "error from user's MakeService", diff --git a/src/proto/h1/conn.rs b/src/proto/h1/conn.rs index e09a6e3da1..66b2cdacc3 100644 --- a/src/proto/h1/conn.rs +++ b/src/proto/h1/conn.rs @@ -686,10 +686,8 @@ where Writing::KeepAlive } } - Err(_not_eof) => { - res = Err(crate::Error::new_user_body( - crate::Error::new_body_write_aborted(), - )); + Err(not_eof) => { + res = Err(crate::Error::new_body_write_aborted().with(not_eof)); Writing::Closed } } diff --git a/src/proto/h1/encode.rs b/src/proto/h1/encode.rs index 703f4f4fb9..f0aa261a4f 100644 --- a/src/proto/h1/encode.rs +++ b/src/proto/h1/encode.rs @@ -22,7 +22,7 @@ pub(crate) struct EncodedBuf { } #[derive(Debug)] -pub(crate) struct NotEof; +pub(crate) struct NotEof(u64); #[derive(Debug, PartialEq, Clone)] enum Kind { @@ -98,7 +98,7 @@ impl Encoder { })), #[cfg(feature = "server")] Kind::CloseDelimited => Ok(None), - Kind::Length(_) => Err(NotEof), + Kind::Length(n) => Err(NotEof(n)), } } @@ -351,6 +351,14 @@ impl From, StaticBuf>> for EncodedBuf { } } +impl fmt::Display for NotEof { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "early end, expected {} more bytes", self.0) + } +} + +impl std::error::Error for NotEof {} + #[cfg(test)] mod tests { use bytes::BufMut;