micro_http/protocol/
error.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
//! Error types for HTTP protocol handling
//!
//! This module provides error types for handling various error conditions that may occur
//! during HTTP request processing and response generation.
//!
//! # Error Types
//!
//! - [`HttpError`]: The top-level error type that wraps all other error types
//!   - [`ParseError`]: Errors that occur during request parsing and processing
//!   - [`SendError`]: Errors that occur during response generation and sending
//!
//! The error types form a hierarchy where `HttpError` is the top-level error that can
//! contain either a `ParseError` or `SendError`. This allows for granular error handling
//! while still providing a unified error type at the API boundary.
use std::io;
use thiserror::Error;

/// The top-level error type for HTTP operations
///
/// This enum represents all possible errors that can occur during HTTP request
/// processing and response generation.
#[derive(Debug, Error)]
pub enum HttpError {
    /// Errors that occur during request parsing and processing
    #[error("request error: {source}")]
    RequestError {
        #[from]
        source: ParseError,
    },

    /// Errors that occur during response generation and sending
    #[error("response error: {source}")]
    ResponseError {
        #[from]
        source: SendError,
    },
}

/// Errors that occur during HTTP request parsing
///
/// This enum represents various error conditions that can occur while parsing
/// and processing HTTP requests.
#[derive(Error, Debug)]
pub enum ParseError {
    /// Header size exceeds the maximum allowed size
    #[error("header size too large, current: {current_size} exceed the limit {max_size}")]
    TooLargeHeader { current_size: usize, max_size: usize },

    /// Number of headers exceeds the maximum allowed
    #[error("header number exceed the limit {max_num}")]
    TooManyHeaders { max_num: usize },

    /// Invalid header format or content
    #[error("invalid header: {reason}")]
    InvalidHeader { reason: String },

    /// Unsupported HTTP version
    #[error("invalid http version: {0:?}")]
    InvalidVersion(Option<u8>),

    /// Invalid or unsupported HTTP method
    #[error("invalid http method")]
    InvalidMethod,

    /// Invalid URI format
    #[error("invalid http uri")]
    InvalidUri,

    /// Invalid Content-Length header
    #[error("invalid content-length header: {reason}")]
    InvalidContentLength { reason: String },

    /// Invalid request body
    #[error("invalid body: {reason}")]
    InvalidBody { reason: String },

    /// I/O error during parsing
    #[error("io error: {source}")]
    Io {
        #[from]
        source: io::Error,
    },
}

impl ParseError {
    /// Creates a new TooLargeHeader error
    pub fn too_large_header(current_size: usize, max_size: usize) -> Self {
        Self::TooLargeHeader { current_size, max_size }
    }

    /// Creates a new TooManyHeaders error
    pub fn too_many_headers(max_num: usize) -> Self {
        Self::TooManyHeaders { max_num }
    }

    /// Creates a new InvalidHeader error
    pub fn invalid_header<S: ToString>(str: S) -> Self {
        Self::InvalidHeader { reason: str.to_string() }
    }

    /// Creates a new InvalidBody error
    pub fn invalid_body<S: ToString>(str: S) -> Self {
        Self::InvalidBody { reason: str.to_string() }
    }

    /// Creates a new InvalidContentLength error
    pub fn invalid_content_length<S: ToString>(str: S) -> Self {
        Self::InvalidContentLength { reason: str.to_string() }
    }

    /// Creates a new I/O error
    pub fn io<E: Into<io::Error>>(e: E) -> Self {
        Self::Io { source: e.into() }
    }
}

/// Errors that occur during HTTP response generation and sending
///
/// This enum represents error conditions that can occur while generating
/// and sending HTTP responses.
#[derive(Error, Debug)]
pub enum SendError {
    /// Invalid response body
    #[error("invalid body: {reason}")]
    InvalidBody { reason: String },

    /// I/O error during sending
    #[error("io error: {source}")]
    Io {
        #[from]
        source: io::Error,
    },
}

impl SendError {
    /// Creates a new InvalidBody error
    pub fn invalid_body<S: ToString>(str: S) -> Self {
        Self::InvalidBody { reason: str.to_string() }
    }

    /// Creates a new I/O error
    pub fn io<E: Into<io::Error>>(e: E) -> Self {
        Self::Io { source: e.into() }
    }
}