Skip to content

Commit

Permalink
standardize error messages in actix-http
Browse files Browse the repository at this point in the history
  • Loading branch information
robjtede committed Mar 13, 2023
1 parent 442fa27 commit 5e29726
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 54 deletions.
66 changes: 32 additions & 34 deletions actix-http/src/error.rs
Expand Up @@ -161,44 +161,44 @@ impl From<crate::ws::ProtocolError> for Error {
#[non_exhaustive]
pub enum ParseError {
/// An invalid `Method`, such as `GE.T`.
#[display(fmt = "Invalid Method specified")]
#[display(fmt = "invalid method specified")]
Method,

/// An invalid `Uri`, such as `exam ple.domain`.
#[display(fmt = "Uri error: {}", _0)]
#[display(fmt = "URI error: {}", _0)]
Uri(InvalidUri),

/// An invalid `HttpVersion`, such as `HTP/1.1`
#[display(fmt = "Invalid HTTP version specified")]
#[display(fmt = "invalid HTTP version specified")]
Version,

/// An invalid `Header`.
#[display(fmt = "Invalid Header provided")]
#[display(fmt = "invalid Header provided")]
Header,

/// A message head is too large to be reasonable.
#[display(fmt = "Message head is too large")]
#[display(fmt = "message head is too large")]
TooLarge,

/// A message reached EOF, but is not complete.
#[display(fmt = "Message is incomplete")]
#[display(fmt = "message is incomplete")]
Incomplete,

/// An invalid `Status`, such as `1337 ELITE`.
#[display(fmt = "Invalid Status provided")]
#[display(fmt = "invalid status provided")]
Status,

/// A timeout occurred waiting for an IO event.
#[allow(dead_code)]
#[display(fmt = "Timeout")]
#[display(fmt = "timeout")]
Timeout,

/// An `io::Error` that occurred while trying to read or write to a network stream.
#[display(fmt = "IO error: {}", _0)]
/// An I/O error that occurred while trying to read or write to a network stream.
#[display(fmt = "I/O error: {}", _0)]
Io(io::Error),

/// Parsing a field as string failed.
#[display(fmt = "UTF8 error: {}", _0)]
#[display(fmt = "UTF-8 error: {}", _0)]
Utf8(Utf8Error),
}

Expand Down Expand Up @@ -257,22 +257,19 @@ impl From<ParseError> for Response<BoxBody> {
#[non_exhaustive]
pub enum PayloadError {
/// A payload reached EOF, but is not complete.
#[display(
fmt = "A payload reached EOF, but is not complete. Inner error: {:?}",
_0
)]
#[display(fmt = "payload reached EOF before completing: {:?}", _0)]
Incomplete(Option<io::Error>),

/// Content encoding stream corruption.
#[display(fmt = "Can not decode content-encoding.")]
#[display(fmt = "can not decode content-encoding")]
EncodingCorrupted,

/// Payload reached size limit.
#[display(fmt = "Payload reached size limit.")]
#[display(fmt = "payload reached size limit")]
Overflow,

/// Payload length is unknown.
#[display(fmt = "Payload length is unknown.")]
#[display(fmt = "payload length is unknown")]
UnknownLength,

/// HTTP/2 payload error.
Expand Down Expand Up @@ -330,22 +327,23 @@ impl From<PayloadError> for Error {
#[non_exhaustive]
pub enum DispatchError {
/// Service error.
#[display(fmt = "Service Error")]
#[display(fmt = "service error")]
Service(Response<BoxBody>),

/// Body streaming error.
#[display(fmt = "Body error: {}", _0)]
#[display(fmt = "body error: {}", _0)]
Body(Box<dyn StdError>),

/// Upgrade service error.
#[display(fmt = "upgrade error")]
Upgrade,

/// An `io::Error` that occurred while trying to read or write to a network stream.
#[display(fmt = "IO error: {}", _0)]
#[display(fmt = "I/O error: {}", _0)]
Io(io::Error),

/// Request parse error.
#[display(fmt = "Request parse error: {}", _0)]
#[display(fmt = "request parse error: {}", _0)]
Parse(ParseError),

/// HTTP/2 error.
Expand All @@ -354,19 +352,19 @@ pub enum DispatchError {
H2(h2::Error),

/// The first request did not complete within the specified timeout.
#[display(fmt = "The first request did not complete within the specified timeout")]
#[display(fmt = "request did not complete within the specified timeout")]
SlowRequestTimeout,

/// Disconnect timeout. Makes sense for ssl streams.
#[display(fmt = "Connection shutdown timeout")]
/// Disconnect timeout. Makes sense for TLS streams.
#[display(fmt = "connection shutdown timeout")]
DisconnectTimeout,

/// Handler dropped payload before reading EOF.
#[display(fmt = "Handler dropped payload before reading EOF")]
#[display(fmt = "handler dropped payload before reading EOF")]
HandlerDroppedPayload,

/// Internal error.
#[display(fmt = "Internal error")]
#[display(fmt = "internal error")]
InternalError,
}

Expand All @@ -391,12 +389,12 @@ impl StdError for DispatchError {
#[cfg_attr(test, derive(PartialEq, Eq))]
#[non_exhaustive]
pub enum ContentTypeError {
/// Can not parse content type
#[display(fmt = "Can not parse content type")]
/// Can not parse content type.
#[display(fmt = "could not parse content type")]
ParseError,

/// Unknown content encoding
#[display(fmt = "Unknown content encoding")]
/// Unknown content encoding.
#[display(fmt = "unknown content encoding")]
UnknownEncoding,
}

Expand Down Expand Up @@ -424,7 +422,7 @@ mod tests {
let err: Error = ParseError::Io(orig).into();
assert_eq!(
format!("{}", err),
"error parsing HTTP message: IO error: other"
"error parsing HTTP message: I/O error: other"
);
}

Expand All @@ -451,7 +449,7 @@ mod tests {
let err = PayloadError::Incomplete(None);
assert_eq!(
err.to_string(),
"A payload reached EOF, but is not complete. Inner error: None"
"payload reached EOF before completing: None"
);
}

Expand All @@ -471,7 +469,7 @@ mod tests {
match ParseError::from($from) {
e @ $error => {
let desc = format!("{}", e);
assert_eq!(desc, format!("IO error: {}", $from));
assert_eq!(desc, format!("I/O error: {}", $from));
}
_ => unreachable!("{:?}", $from),
}
Expand Down
32 changes: 16 additions & 16 deletions actix-http/src/ws/mod.rs
Expand Up @@ -26,39 +26,39 @@ pub use self::proto::{hash_key, CloseCode, CloseReason, OpCode};
#[derive(Debug, Display, Error, From)]
pub enum ProtocolError {
/// Received an unmasked frame from client.
#[display(fmt = "Received an unmasked frame from client.")]
#[display(fmt = "received an unmasked frame from client")]
UnmaskedFrame,

/// Received a masked frame from server.
#[display(fmt = "Received a masked frame from server.")]
#[display(fmt = "received a masked frame from server")]
MaskedFrame,

/// Encountered invalid opcode.
#[display(fmt = "Invalid opcode: {}.", _0)]
#[display(fmt = "invalid opcode ({})", _0)]
InvalidOpcode(#[error(not(source))] u8),

/// Invalid control frame length
#[display(fmt = "Invalid control frame length: {}.", _0)]
#[display(fmt = "invalid control frame length ({})", _0)]
InvalidLength(#[error(not(source))] usize),

/// Bad opcode.
#[display(fmt = "Bad opcode.")]
#[display(fmt = "bad opcode")]
BadOpCode,

/// A payload reached size limit.
#[display(fmt = "A payload reached size limit.")]
#[display(fmt = "payload reached size limit")]
Overflow,

/// Continuation is not started.
#[display(fmt = "Continuation is not started.")]
/// Continuation has not started.
#[display(fmt = "continuation has not started")]
ContinuationNotStarted,

/// Received new continuation but it is already started.
#[display(fmt = "Received new continuation but it is already started.")]
#[display(fmt = "received new continuation but it has already started")]
ContinuationStarted,

/// Unknown continuation fragment.
#[display(fmt = "Unknown continuation fragment: {}.", _0)]
#[display(fmt = "unknown continuation fragment: {}", _0)]
ContinuationFragment(#[error(not(source))] OpCode),

/// I/O error.
Expand All @@ -70,27 +70,27 @@ pub enum ProtocolError {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Display, Error)]
pub enum HandshakeError {
/// Only get method is allowed.
#[display(fmt = "Method not allowed.")]
#[display(fmt = "method not allowed")]
GetMethodRequired,

/// Upgrade header if not set to WebSocket.
#[display(fmt = "WebSocket upgrade is expected.")]
#[display(fmt = "WebSocket upgrade is expected")]
NoWebsocketUpgrade,

/// Connection header is not set to upgrade.
#[display(fmt = "Connection upgrade is expected.")]
#[display(fmt = "connection upgrade is expected")]
NoConnectionUpgrade,

/// WebSocket version header is not set.
#[display(fmt = "WebSocket version header is required.")]
#[display(fmt = "WebSocket version header is required")]
NoVersionHeader,

/// Unsupported WebSocket version.
#[display(fmt = "Unsupported WebSocket version.")]
#[display(fmt = "unsupported WebSocket version")]
UnsupportedVersion,

/// WebSocket key is not set or wrong.
#[display(fmt = "Unknown websocket key.")]
#[display(fmt = "unknown WebSocket key")]
BadWebsocketKey,
}

Expand Down
6 changes: 3 additions & 3 deletions actix-http/tests/test_ws.rs
Expand Up @@ -39,13 +39,13 @@ impl WsService {

#[derive(Debug, Display, Error, From)]
enum WsServiceError {
#[display(fmt = "http error")]
#[display(fmt = "HTTP error")]
Http(actix_http::Error),

#[display(fmt = "ws handshake error")]
#[display(fmt = "WS handshake error")]
Ws(actix_http::ws::HandshakeError),

#[display(fmt = "io error")]
#[display(fmt = "I/O error")]
Io(std::io::Error),

#[display(fmt = "dispatcher error")]
Expand Down
2 changes: 1 addition & 1 deletion actix-web/src/error/response_error.rs
Expand Up @@ -152,7 +152,7 @@ mod tests {
let resp_err: &dyn ResponseError = &err;

let err = resp_err.downcast_ref::<PayloadError>().unwrap();
assert_eq!(err.to_string(), "Payload reached size limit.");
assert_eq!(err.to_string(), "payload reached size limit");

let not_err = resp_err.downcast_ref::<ContentTypeError>();
assert!(not_err.is_none());
Expand Down

0 comments on commit 5e29726

Please sign in to comment.