wasmtime_wasi_http/p2/
error.rs1use crate::FieldMapError;
2use crate::p2::bindings::http::types::{self, ErrorCode};
3use std::error::Error;
4use std::fmt;
5use wasmtime::component::ResourceTableError;
6
7pub type HttpResult<T, E = HttpError> = Result<T, E>;
9
10#[repr(transparent)]
15pub struct HttpError {
16 err: wasmtime::Error,
17}
18
19impl HttpError {
20 pub fn trap(err: impl Into<wasmtime::Error>) -> HttpError {
22 HttpError { err: err.into() }
23 }
24
25 pub fn downcast(self) -> wasmtime::Result<ErrorCode> {
27 self.err.downcast()
28 }
29
30 pub fn downcast_ref(&self) -> Option<&ErrorCode> {
32 self.err.downcast_ref()
33 }
34}
35
36impl From<ErrorCode> for HttpError {
37 fn from(error: ErrorCode) -> Self {
38 Self { err: error.into() }
39 }
40}
41
42impl From<ResourceTableError> for HttpError {
43 fn from(error: ResourceTableError) -> Self {
44 HttpError::trap(error)
45 }
46}
47
48impl fmt::Debug for HttpError {
49 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50 self.err.fmt(f)
51 }
52}
53
54impl fmt::Display for HttpError {
55 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56 self.err.fmt(f)
57 }
58}
59
60impl Error for HttpError {}
61
62pub type HeaderResult<T, E = HeaderError> = Result<T, E>;
64
65#[repr(transparent)]
70pub struct HeaderError {
71 err: wasmtime::Error,
72}
73
74impl HeaderError {
75 pub fn trap(err: impl Into<wasmtime::Error>) -> HeaderError {
77 HeaderError { err: err.into() }
78 }
79
80 pub fn downcast(self) -> wasmtime::Result<types::HeaderError> {
82 self.err.downcast()
83 }
84
85 pub fn downcast_ref(&self) -> Option<&types::HeaderError> {
87 self.err.downcast_ref()
88 }
89}
90
91impl From<types::HeaderError> for HeaderError {
92 fn from(error: types::HeaderError) -> Self {
93 Self { err: error.into() }
94 }
95}
96
97impl From<ResourceTableError> for HeaderError {
98 fn from(error: ResourceTableError) -> Self {
99 HeaderError::trap(error)
100 }
101}
102
103impl From<http::header::InvalidHeaderName> for HeaderError {
104 fn from(_: http::header::InvalidHeaderName) -> Self {
105 HeaderError::from(types::HeaderError::InvalidSyntax)
106 }
107}
108
109impl From<http::header::InvalidHeaderValue> for HeaderError {
110 fn from(_: http::header::InvalidHeaderValue) -> Self {
111 HeaderError::from(types::HeaderError::InvalidSyntax)
112 }
113}
114
115impl From<FieldMapError> for HeaderError {
116 fn from(err: FieldMapError) -> Self {
117 match err {
118 FieldMapError::Immutable => types::HeaderError::Immutable.into(),
119 FieldMapError::InvalidHeaderName => types::HeaderError::InvalidSyntax.into(),
120 FieldMapError::TooManyFields | FieldMapError::TotalSizeTooBig => HeaderError::trap(err),
121 }
122 }
123}
124
125impl fmt::Debug for HeaderError {
126 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
127 self.err.fmt(f)
128 }
129}
130
131impl fmt::Display for HeaderError {
132 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
133 self.err.fmt(f)
134 }
135}
136
137#[cfg(feature = "default-send-request")]
138pub(crate) fn dns_error(rcode: String, info_code: u16) -> ErrorCode {
139 ErrorCode::DnsError(crate::p2::bindings::http::types::DnsErrorPayload {
140 rcode: Some(rcode),
141 info_code: Some(info_code),
142 })
143}
144
145pub(crate) fn internal_error(msg: String) -> ErrorCode {
146 ErrorCode::InternalError(Some(msg))
147}
148
149pub fn http_request_error(err: http::Error) -> ErrorCode {
151 if err.is::<http::uri::InvalidUri>() {
152 return ErrorCode::HttpRequestUriInvalid;
153 }
154
155 tracing::warn!("http request error: {err:?}");
156
157 ErrorCode::HttpProtocolError
158}
159
160pub fn hyper_request_error(err: hyper::Error) -> ErrorCode {
162 if let Some(cause) = err.source() {
164 if let Some(err) = cause.downcast_ref::<ErrorCode>() {
165 return err.clone();
166 }
167 }
168
169 tracing::warn!("hyper request error: {err:?}");
170
171 ErrorCode::HttpProtocolError
172}
173
174pub fn hyper_response_error(err: hyper::Error) -> ErrorCode {
176 if err.is_timeout() {
177 return ErrorCode::HttpResponseTimeout;
178 }
179
180 if let Some(cause) = err.source() {
182 if let Some(err) = cause.downcast_ref::<ErrorCode>() {
183 return err.clone();
184 }
185 }
186
187 tracing::warn!("hyper response error: {err:?}");
188
189 ErrorCode::HttpProtocolError
190}
191
192impl From<hyper::Error> for ErrorCode {
193 fn from(err: hyper::Error) -> Self {
194 hyper_response_error(err)
195 }
196}