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}