1use wasm_bindgen::JsValue;
8
9#[derive(Debug, thiserror::Error)]
11pub enum LibfwError {
12 #[error("http {status} for `{url}`")]
14 Http { status: u16, url: String },
15 #[error("network error: {0}")]
17 Network(String),
18 #[error("decompression error: {0}")]
20 Decompress(String),
21 #[error("compression error: {0}")]
23 Compress(String),
24 #[error("protocol error: {0}")]
26 Protocol(String),
27 #[error("js error: {0}")]
29 Js(String),
30 #[error("transfer cancelled")]
32 Cancelled,
33 #[error("storage error: {0}")]
35 Storage(String),
36}
37
38impl LibfwError {
39 pub fn to_js(&self) -> JsValue {
41 let msg = self.to_string();
42 let err = js_sys::Error::new(&msg);
43 let _ = js_sys::Reflect::set(
45 &err,
46 &JsValue::from_str("isLibfwError"),
47 &JsValue::TRUE,
48 );
49 err.into()
50 }
51}
52
53impl From<JsValue> for LibfwError {
54 fn from(value: JsValue) -> Self {
55 LibfwError::Js(
56 value
57 .as_string()
58 .unwrap_or_else(|| format!("{value:?}")),
59 )
60 }
61}
62
63impl From<libfw_core::error::DecompressError> for LibfwError {
64 fn from(e: libfw_core::error::DecompressError) -> Self {
65 LibfwError::Decompress(e.to_string())
66 }
67}
68
69impl From<libfw_core::error::CompressError> for LibfwError {
70 fn from(e: libfw_core::error::CompressError) -> Self {
71 LibfwError::Compress(e.to_string())
72 }
73}
74
75pub fn js_value_string(v: &JsValue) -> String {
77 v.as_string().unwrap_or_else(|| format!("{v:?}"))
78}
79
80#[cfg(test)]
81mod tests {
82 use super::*;
83
84 #[test]
85 fn error_messages_are_stable() {
86 assert_eq!(
87 LibfwError::Http {
88 status: 404,
89 url: "/f".into()
90 }
91 .to_string(),
92 "http 404 for `/f`"
93 );
94 assert_eq!(LibfwError::Cancelled.to_string(), "transfer cancelled");
95 }
96
97 #[test]
98 #[cfg(target_arch = "wasm32")]
99 fn js_errors_carry_tag() {
100 let js = LibfwError::Cancelled.to_js();
101 let err = js_sys::Error::from(js);
102 let tag = js_sys::Reflect::get(&err, &JsValue::from_str("isLibfwError"))
103 .ok()
104 .and_then(|v| v.as_bool())
105 .unwrap_or(false);
106 assert!(tag);
107 }
108}