use thiserror::Error;
use wasm_bindgen::prelude::*;
#[derive(Error, Debug)]
pub enum WasmError {
#[error("Parse error: {0}")]
ParseError(String),
#[error("Query error: {0}")]
QueryError(String),
#[error("Store error: {0}")]
StoreError(String),
#[error("Validation error: {0}")]
ValidationError(String),
#[error("Serialization error: {0}")]
SerializationError(String),
#[error("Not implemented: {0}")]
NotImplemented(String),
}
impl WasmError {
pub fn code(&self) -> &'static str {
match self {
WasmError::ParseError(_) => "ParseError",
WasmError::QueryError(_) => "QueryError",
WasmError::StoreError(_) => "StoreError",
WasmError::ValidationError(_) => "ValidationError",
WasmError::SerializationError(_) => "SerializationError",
WasmError::NotImplemented(_) => "NotImplemented",
}
}
}
impl From<WasmError> for JsValue {
#[cfg(target_arch = "wasm32")]
fn from(error: WasmError) -> Self {
let code = error.code();
let js_error = js_sys::Error::new(&error.to_string());
js_error.set_name(code);
let _ = js_sys::Reflect::set(
&js_error,
&JsValue::from_str("code"),
&JsValue::from_str(code),
);
js_error.into()
}
#[cfg(not(target_arch = "wasm32"))]
fn from(error: WasmError) -> Self {
JsValue::from_str(&error.to_string())
}
}
pub type WasmResult<T> = Result<T, WasmError>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn regression_error_code_matches_variant() {
assert_eq!(WasmError::ParseError("x".into()).code(), "ParseError");
assert_eq!(WasmError::QueryError("x".into()).code(), "QueryError");
assert_eq!(WasmError::StoreError("x".into()).code(), "StoreError");
assert_eq!(
WasmError::ValidationError("x".into()).code(),
"ValidationError"
);
assert_eq!(
WasmError::SerializationError("x".into()).code(),
"SerializationError"
);
assert_eq!(
WasmError::NotImplemented("x".into()).code(),
"NotImplemented"
);
}
}