wasmtime_wasi_http/
error.rs1use crate::bindings::http::types::ErrorCode;
2use std::error::Error;
3use std::fmt;
4use wasmtime::component::ResourceTableError;
5
6pub type HttpResult<T, E = HttpError> = Result<T, E>;
8
9#[repr(transparent)]
14pub struct HttpError {
15 err: anyhow::Error,
16}
17
18impl HttpError {
19 pub fn trap(err: impl Into<anyhow::Error>) -> HttpError {
21 HttpError { err: err.into() }
22 }
23
24 pub fn downcast(self) -> anyhow::Result<ErrorCode> {
26 self.err.downcast()
27 }
28
29 pub fn downcast_ref(&self) -> Option<&ErrorCode> {
31 self.err.downcast_ref()
32 }
33}
34
35impl From<ErrorCode> for HttpError {
36 fn from(error: ErrorCode) -> Self {
37 Self { err: error.into() }
38 }
39}
40
41impl From<ResourceTableError> for HttpError {
42 fn from(error: ResourceTableError) -> Self {
43 HttpError::trap(error)
44 }
45}
46
47impl fmt::Debug for HttpError {
48 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49 self.err.fmt(f)
50 }
51}
52
53impl fmt::Display for HttpError {
54 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55 self.err.fmt(f)
56 }
57}
58
59impl Error for HttpError {}
60
61#[cfg(feature = "default-send-request")]
62pub(crate) fn dns_error(rcode: String, info_code: u16) -> ErrorCode {
63 ErrorCode::DnsError(crate::bindings::http::types::DnsErrorPayload {
64 rcode: Some(rcode),
65 info_code: Some(info_code),
66 })
67}
68
69pub(crate) fn internal_error(msg: String) -> ErrorCode {
70 ErrorCode::InternalError(Some(msg))
71}
72
73pub fn http_request_error(err: http::Error) -> ErrorCode {
75 if err.is::<http::uri::InvalidUri>() {
76 return ErrorCode::HttpRequestUriInvalid;
77 }
78
79 tracing::warn!("http request error: {err:?}");
80
81 ErrorCode::HttpProtocolError
82}
83
84pub fn hyper_request_error(err: hyper::Error) -> ErrorCode {
86 if let Some(cause) = err.source() {
88 if let Some(err) = cause.downcast_ref::<ErrorCode>() {
89 return err.clone();
90 }
91 }
92
93 tracing::warn!("hyper request error: {err:?}");
94
95 ErrorCode::HttpProtocolError
96}
97
98pub fn hyper_response_error(err: hyper::Error) -> ErrorCode {
100 if err.is_timeout() {
101 return ErrorCode::HttpResponseTimeout;
102 }
103
104 if let Some(cause) = err.source() {
106 if let Some(err) = cause.downcast_ref::<ErrorCode>() {
107 return err.clone();
108 }
109 }
110
111 tracing::warn!("hyper response error: {err:?}");
112
113 ErrorCode::HttpProtocolError
114}