Coverage Report

Created: 2025-07-11 06:53

/src/http/src/error.rs
Line
Count
Source (jump to first uncovered line)
1
use std::error;
2
use std::fmt;
3
use std::result;
4
5
use crate::header;
6
use crate::header::MaxSizeReached;
7
use crate::method;
8
use crate::status;
9
use crate::uri;
10
11
/// A generic "error" for HTTP connections
12
///
13
/// This error type is less specific than the error returned from other
14
/// functions in this crate, but all other errors can be converted to this
15
/// error. Consumers of this crate can typically consume and work with this form
16
/// of error for conversions with the `?` operator.
17
pub struct Error {
18
    inner: ErrorKind,
19
}
20
21
/// A `Result` typedef to use with the `http::Error` type
22
pub type Result<T> = result::Result<T, Error>;
23
24
enum ErrorKind {
25
    StatusCode(status::InvalidStatusCode),
26
    Method(method::InvalidMethod),
27
    Uri(uri::InvalidUri),
28
    UriParts(uri::InvalidUriParts),
29
    HeaderName(header::InvalidHeaderName),
30
    HeaderValue(header::InvalidHeaderValue),
31
    MaxSizeReached(MaxSizeReached),
32
}
33
34
impl fmt::Debug for Error {
35
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
36
0
        f.debug_tuple("http::Error")
37
0
            // Skip the noise of the ErrorKind enum
38
0
            .field(&self.get_ref())
39
0
            .finish()
40
0
    }
41
}
42
43
impl fmt::Display for Error {
44
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45
0
        fmt::Display::fmt(self.get_ref(), f)
46
0
    }
47
}
48
49
impl Error {
50
    /// Return true if the underlying error has the same type as T.
51
0
    pub fn is<T: error::Error + 'static>(&self) -> bool {
52
0
        self.get_ref().is::<T>()
53
0
    }
54
55
    /// Return a reference to the lower level, inner error.
56
0
    pub fn get_ref(&self) -> &(dyn error::Error + 'static) {
57
        use self::ErrorKind::*;
58
59
0
        match self.inner {
60
0
            StatusCode(ref e) => e,
61
0
            Method(ref e) => e,
62
0
            Uri(ref e) => e,
63
0
            UriParts(ref e) => e,
64
0
            HeaderName(ref e) => e,
65
0
            HeaderValue(ref e) => e,
66
0
            MaxSizeReached(ref e) => e,
67
        }
68
0
    }
69
}
70
71
impl error::Error for Error {
72
    // Return any available cause from the inner error. Note the inner error is
73
    // not itself the cause.
74
0
    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
75
0
        self.get_ref().source()
76
0
    }
77
}
78
79
impl From<MaxSizeReached> for Error {
80
0
    fn from(err: MaxSizeReached) -> Error {
81
0
        Error {
82
0
            inner: ErrorKind::MaxSizeReached(err),
83
0
        }
84
0
    }
85
}
86
87
impl From<status::InvalidStatusCode> for Error {
88
0
    fn from(err: status::InvalidStatusCode) -> Error {
89
0
        Error {
90
0
            inner: ErrorKind::StatusCode(err),
91
0
        }
92
0
    }
93
}
94
95
impl From<method::InvalidMethod> for Error {
96
0
    fn from(err: method::InvalidMethod) -> Error {
97
0
        Error {
98
0
            inner: ErrorKind::Method(err),
99
0
        }
100
0
    }
101
}
102
103
impl From<uri::InvalidUri> for Error {
104
3.98k
    fn from(err: uri::InvalidUri) -> Error {
105
3.98k
        Error {
106
3.98k
            inner: ErrorKind::Uri(err),
107
3.98k
        }
108
3.98k
    }
109
}
110
111
impl From<uri::InvalidUriParts> for Error {
112
0
    fn from(err: uri::InvalidUriParts) -> Error {
113
0
        Error {
114
0
            inner: ErrorKind::UriParts(err),
115
0
        }
116
0
    }
117
}
118
119
impl From<header::InvalidHeaderName> for Error {
120
6.32k
    fn from(err: header::InvalidHeaderName) -> Error {
121
6.32k
        Error {
122
6.32k
            inner: ErrorKind::HeaderName(err),
123
6.32k
        }
124
6.32k
    }
125
}
126
127
impl From<header::InvalidHeaderValue> for Error {
128
95
    fn from(err: header::InvalidHeaderValue) -> Error {
129
95
        Error {
130
95
            inner: ErrorKind::HeaderValue(err),
131
95
        }
132
95
    }
133
}
134
135
impl From<std::convert::Infallible> for Error {
136
    fn from(err: std::convert::Infallible) -> Error {
137
        match err {}
138
    }
139
}
140
141
#[cfg(test)]
142
mod tests {
143
    use super::*;
144
145
    #[test]
146
    fn inner_error_is_invalid_status_code() {
147
        if let Err(e) = status::StatusCode::from_u16(6666) {
148
            let err: Error = e.into();
149
            let ie = err.get_ref();
150
            assert!(!ie.is::<header::InvalidHeaderValue>());
151
            assert!(ie.is::<status::InvalidStatusCode>());
152
            ie.downcast_ref::<status::InvalidStatusCode>().unwrap();
153
154
            assert!(!err.is::<header::InvalidHeaderValue>());
155
            assert!(err.is::<status::InvalidStatusCode>());
156
        } else {
157
            panic!("Bad status allowed!");
158
        }
159
    }
160
}