refactor(error): improve error message when user body ends early

This commit is contained in:
Sean McArthur
2022-03-11 17:44:06 -08:00
parent 1e9cd4f292
commit 740654e55d
3 changed files with 17 additions and 11 deletions

View File

@@ -53,8 +53,6 @@ pub(super) enum Kind {
/// Error while writing a body to connection. /// Error while writing a body to connection.
#[cfg(any(feature = "http1", feature = "http2"))] #[cfg(any(feature = "http1", feature = "http2"))]
BodyWrite, BodyWrite,
/// The body write was aborted.
BodyWriteAborted,
/// Error calling AsyncWrite::shutdown() /// Error calling AsyncWrite::shutdown()
#[cfg(feature = "http1")] #[cfg(feature = "http1")]
Shutdown, Shutdown,
@@ -96,6 +94,8 @@ pub(super) enum User {
/// Error calling user's HttpBody::poll_data(). /// Error calling user's HttpBody::poll_data().
#[cfg(any(feature = "http1", feature = "http2"))] #[cfg(any(feature = "http1", feature = "http2"))]
Body, Body,
/// The user aborted writing of the outgoing body.
BodyWriteAborted,
/// Error calling user's MakeService. /// Error calling user's MakeService.
#[cfg(any(feature = "http1", feature = "http2"))] #[cfg(any(feature = "http1", feature = "http2"))]
#[cfg(feature = "server")] #[cfg(feature = "server")]
@@ -193,7 +193,7 @@ impl Error {
/// Returns true if the body write was aborted. /// Returns true if the body write was aborted.
pub fn is_body_write_aborted(&self) -> bool { 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. /// Returns true if the error was caused by a timeout.
@@ -305,7 +305,7 @@ impl Error {
} }
pub(super) fn new_body_write_aborted() -> 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 { fn new_user(user: User) -> Error {
@@ -444,7 +444,6 @@ impl Error {
Kind::Body => "error reading a body from connection", Kind::Body => "error reading a body from connection",
#[cfg(any(feature = "http1", feature = "http2"))] #[cfg(any(feature = "http1", feature = "http2"))]
Kind::BodyWrite => "error writing a body to connection", Kind::BodyWrite => "error writing a body to connection",
Kind::BodyWriteAborted => "body write aborted",
#[cfg(feature = "http1")] #[cfg(feature = "http1")]
Kind::Shutdown => "error shutting down connection", Kind::Shutdown => "error shutting down connection",
#[cfg(feature = "http2")] #[cfg(feature = "http2")]
@@ -454,6 +453,7 @@ impl Error {
#[cfg(any(feature = "http1", feature = "http2"))] #[cfg(any(feature = "http1", feature = "http2"))]
Kind::User(User::Body) => "error from user's HttpBody stream", 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(any(feature = "http1", feature = "http2"))]
#[cfg(feature = "server")] #[cfg(feature = "server")]
Kind::User(User::MakeService) => "error from user's MakeService", Kind::User(User::MakeService) => "error from user's MakeService",

View File

@@ -686,10 +686,8 @@ where
Writing::KeepAlive Writing::KeepAlive
} }
} }
Err(_not_eof) => { Err(not_eof) => {
res = Err(crate::Error::new_user_body( res = Err(crate::Error::new_body_write_aborted().with(not_eof));
crate::Error::new_body_write_aborted(),
));
Writing::Closed Writing::Closed
} }
} }

View File

@@ -22,7 +22,7 @@ pub(crate) struct EncodedBuf<B> {
} }
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct NotEof; pub(crate) struct NotEof(u64);
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
enum Kind { enum Kind {
@@ -98,7 +98,7 @@ impl Encoder {
})), })),
#[cfg(feature = "server")] #[cfg(feature = "server")]
Kind::CloseDelimited => Ok(None), Kind::CloseDelimited => Ok(None),
Kind::Length(_) => Err(NotEof), Kind::Length(n) => Err(NotEof(n)),
} }
} }
@@ -351,6 +351,14 @@ impl<B: Buf> From<Chain<Chain<ChunkSize, B>, StaticBuf>> for EncodedBuf<B> {
} }
} }
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)] #[cfg(test)]
mod tests { mod tests {
use bytes::BufMut; use bytes::BufMut;