micro_http/protocol/
error.rs

1//! Error types for HTTP protocol handling
2//!
3//! This module provides error types for handling various error conditions that may occur
4//! during HTTP request processing and response generation.
5//!
6//! # Error Types
7//!
8//! - [`HttpError`]: The top-level error type that wraps all other error types
9//!   - [`ParseError`]: Errors that occur during request parsing and processing
10//!   - [`SendError`]: Errors that occur during response generation and sending
11//!
12//! The error types form a hierarchy where `HttpError` is the top-level error that can
13//! contain either a `ParseError` or `SendError`. This allows for granular error handling
14//! while still providing a unified error type at the API boundary.
15use std::io;
16use thiserror::Error;
17
18/// The top-level error type for HTTP operations
19///
20/// This enum represents all possible errors that can occur during HTTP request
21/// processing and response generation.
22#[derive(Debug, Error)]
23pub enum HttpError {
24    /// Errors that occur during request parsing and processing
25    #[error("request error: {source}")]
26    RequestError {
27        #[from]
28        source: ParseError,
29    },
30
31    /// Errors that occur during response generation and sending
32    #[error("response error: {source}")]
33    ResponseError {
34        #[from]
35        source: SendError,
36    },
37}
38
39/// Errors that occur during HTTP request parsing
40///
41/// This enum represents various error conditions that can occur while parsing
42/// and processing HTTP requests.
43#[derive(Error, Debug)]
44pub enum ParseError {
45    /// Header size exceeds the maximum allowed size
46    #[error("header size too large, current: {current_size} exceed the limit {max_size}")]
47    TooLargeHeader { current_size: usize, max_size: usize },
48
49    /// Number of headers exceeds the maximum allowed
50    #[error("header number exceed the limit {max_num}")]
51    TooManyHeaders { max_num: usize },
52
53    /// Invalid header format or content
54    #[error("invalid header: {reason}")]
55    InvalidHeader { reason: String },
56
57    /// Unsupported HTTP version
58    #[error("invalid http version: {0:?}")]
59    InvalidVersion(Option<u8>),
60
61    /// Invalid or unsupported HTTP method
62    #[error("invalid http method")]
63    InvalidMethod,
64
65    /// Invalid URI format
66    #[error("invalid http uri")]
67    InvalidUri,
68
69    /// Invalid Content-Length header
70    #[error("invalid content-length header: {reason}")]
71    InvalidContentLength { reason: String },
72
73    /// Invalid request body
74    #[error("invalid body: {reason}")]
75    InvalidBody { reason: String },
76
77    /// I/O error during parsing
78    #[error("io error: {source}")]
79    Io {
80        #[from]
81        source: io::Error,
82    },
83}
84
85impl ParseError {
86    /// Creates a new TooLargeHeader error
87    pub fn too_large_header(current_size: usize, max_size: usize) -> Self {
88        Self::TooLargeHeader { current_size, max_size }
89    }
90
91    /// Creates a new TooManyHeaders error
92    pub fn too_many_headers(max_num: usize) -> Self {
93        Self::TooManyHeaders { max_num }
94    }
95
96    /// Creates a new InvalidHeader error
97    pub fn invalid_header<S: ToString>(str: S) -> Self {
98        Self::InvalidHeader { reason: str.to_string() }
99    }
100
101    /// Creates a new InvalidBody error
102    pub fn invalid_body<S: ToString>(str: S) -> Self {
103        Self::InvalidBody { reason: str.to_string() }
104    }
105
106    /// Creates a new InvalidContentLength error
107    pub fn invalid_content_length<S: ToString>(str: S) -> Self {
108        Self::InvalidContentLength { reason: str.to_string() }
109    }
110
111    /// Creates a new I/O error
112    pub fn io<E: Into<io::Error>>(e: E) -> Self {
113        Self::Io { source: e.into() }
114    }
115}
116
117/// Errors that occur during HTTP response generation and sending
118///
119/// This enum represents error conditions that can occur while generating
120/// and sending HTTP responses.
121#[derive(Error, Debug)]
122pub enum SendError {
123    /// Invalid response body
124    #[error("invalid body: {reason}")]
125    InvalidBody { reason: String },
126
127    /// I/O error during sending
128    #[error("io error: {source}")]
129    Io {
130        #[from]
131        source: io::Error,
132    },
133}
134
135impl SendError {
136    /// Creates a new InvalidBody error
137    pub fn invalid_body<S: ToString>(str: S) -> Self {
138        Self::InvalidBody { reason: str.to_string() }
139    }
140
141    /// Creates a new I/O error
142    pub fn io<E: Into<io::Error>>(e: E) -> Self {
143        Self::Io { source: e.into() }
144    }
145}