Path: blob/main/crates/wasi-http/src/error.rs
1692 views
use crate::bindings::http::types::ErrorCode;1use std::error::Error;2use std::fmt;3use wasmtime::component::ResourceTableError;45/// A [`Result`] type where the error type defaults to [`HttpError`].6pub type HttpResult<T, E = HttpError> = Result<T, E>;78/// A `wasi:http`-specific error type used to represent either a trap or an9/// [`ErrorCode`].10///11/// Modeled after [`TrappableError`](wasmtime_wasi::TrappableError).12#[repr(transparent)]13pub struct HttpError {14err: anyhow::Error,15}1617impl HttpError {18/// Create a new `HttpError` that represents a trap.19pub fn trap(err: impl Into<anyhow::Error>) -> HttpError {20HttpError { err: err.into() }21}2223/// Downcast this error to an [`ErrorCode`].24pub fn downcast(self) -> anyhow::Result<ErrorCode> {25self.err.downcast()26}2728/// Downcast this error to a reference to an [`ErrorCode`]29pub fn downcast_ref(&self) -> Option<&ErrorCode> {30self.err.downcast_ref()31}32}3334impl From<ErrorCode> for HttpError {35fn from(error: ErrorCode) -> Self {36Self { err: error.into() }37}38}3940impl From<ResourceTableError> for HttpError {41fn from(error: ResourceTableError) -> Self {42HttpError::trap(error)43}44}4546impl fmt::Debug for HttpError {47fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {48self.err.fmt(f)49}50}5152impl fmt::Display for HttpError {53fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {54self.err.fmt(f)55}56}5758impl Error for HttpError {}5960#[cfg(feature = "default-send-request")]61pub(crate) fn dns_error(rcode: String, info_code: u16) -> ErrorCode {62ErrorCode::DnsError(crate::bindings::http::types::DnsErrorPayload {63rcode: Some(rcode),64info_code: Some(info_code),65})66}6768pub(crate) fn internal_error(msg: String) -> ErrorCode {69ErrorCode::InternalError(Some(msg))70}7172/// Translate a [`http::Error`] to a wasi-http `ErrorCode` in the context of a request.73pub fn http_request_error(err: http::Error) -> ErrorCode {74if err.is::<http::uri::InvalidUri>() {75return ErrorCode::HttpRequestUriInvalid;76}7778tracing::warn!("http request error: {err:?}");7980ErrorCode::HttpProtocolError81}8283/// Translate a [`hyper::Error`] to a wasi-http `ErrorCode` in the context of a request.84pub fn hyper_request_error(err: hyper::Error) -> ErrorCode {85// If there's a source, we might be able to extract a wasi-http error from it.86if let Some(cause) = err.source() {87if let Some(err) = cause.downcast_ref::<ErrorCode>() {88return err.clone();89}90}9192tracing::warn!("hyper request error: {err:?}");9394ErrorCode::HttpProtocolError95}9697/// Translate a [`hyper::Error`] to a wasi-http `ErrorCode` in the context of a response.98pub fn hyper_response_error(err: hyper::Error) -> ErrorCode {99if err.is_timeout() {100return ErrorCode::HttpResponseTimeout;101}102103// If there's a source, we might be able to extract a wasi-http error from it.104if let Some(cause) = err.source() {105if let Some(err) = cause.downcast_ref::<ErrorCode>() {106return err.clone();107}108}109110tracing::warn!("hyper response error: {err:?}");111112ErrorCode::HttpProtocolError113}114115116