use thiserror::Error as ThisError;
#[derive(Debug, ThisError)]
pub enum Error {
#[cfg(target_arch = "wasm32")]
#[error("an HTTP error occurred")]
Http(
#[from]
#[source]
http::Error,
),
#[error("encountered request header with opaque bytes")]
HttpHeader(
#[from]
#[source]
http::header::ToStrError,
),
#[cfg(not(target_arch = "wasm32"))]
#[error("the hyper crate reported an error")]
Hyper(
#[from]
#[source]
hyper::Error,
),
#[cfg(target_arch = "wasm32")]
#[error("an invalid HTTP status was received")]
InvalidStatusCode(
#[from]
#[source]
http::status::InvalidStatusCode,
),
#[cfg(target_arch = "wasm32")]
#[error("{context}")]
WebSys {
context: String,
#[source]
source: WebError,
},
}
#[cfg(target_arch = "wasm32")]
#[derive(Debug, ThisError)]
#[error("{0}")]
pub struct WebError(String);
#[cfg(target_arch = "wasm32")]
use wasm_bindgen::JsValue;
#[cfg(target_arch = "wasm32")]
impl Error {
pub(crate) fn web<S>(context: S, error: JsValue) -> Error
where
S: Into<String>,
{
let error = if let Some(error) = error.as_string() {
error
} else {
format!("{:?}", error)
};
Self::WebSys {
context: context.into(),
source: WebError(error),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as test;
#[test]
#[allow(clippy::unnecessary_operation)]
fn ensure_error_trait_impls() {
fn err() -> Error {
unimplemented!()
}
if false {
&err() as &(dyn Send + Sync);
}
}
#[cfg(target_arch = "wasm32")]
mod wasm {
use super::test;
use super::*;
use std::error::Error as _;
#[test]
fn web_sys_variant_formatting() {
let source = JsValue::from_str("the one and only source");
let error = Error::web("error context", source);
assert_eq!(error.to_string(), "error context");
assert_eq!(
error.source().unwrap().to_string(),
"the one and only source"
);
}
}
}