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
61pub(crate) fn dns_error(rcode: String, info_code: u16) -> ErrorCode {
62 ErrorCode::DnsError(crate::bindings::http::types::DnsErrorPayload {
63 rcode: Some(rcode),
64 info_code: Some(info_code),
65 })
66}
67
68pub(crate) fn internal_error(msg: String) -> ErrorCode {
69 ErrorCode::InternalError(Some(msg))
70}
71
72pub fn http_request_error(err: http::Error) -> ErrorCode {
74 if err.is::<http::uri::InvalidUri>() {
75 return ErrorCode::HttpRequestUriInvalid;
76 }
77
78 tracing::warn!("http request error: {err:?}");
79
80 ErrorCode::HttpProtocolError
81}
82
83pub fn hyper_request_error(err: hyper::Error) -> ErrorCode {
85 if let Some(cause) = err.source() {
87 if let Some(err) = cause.downcast_ref::<ErrorCode>() {
88 return err.clone();
89 }
90 }
91
92 tracing::warn!("hyper request error: {err:?}");
93
94 ErrorCode::HttpProtocolError
95}
96
97pub fn hyper_response_error(err: hyper::Error) -> ErrorCode {
99 if err.is_timeout() {
100 return ErrorCode::HttpResponseTimeout;
101 }
102
103 if let Some(cause) = err.source() {
105 if let Some(err) = cause.downcast_ref::<ErrorCode>() {
106 return err.clone();
107 }
108 }
109
110 tracing::warn!("hyper response error: {err:?}");
111
112 ErrorCode::HttpProtocolError
113}