1use std::convert::TryFrom;
2use std::fmt;
3use wasm_bindgen::{JsCast, JsValue};
4
5pub struct JsError {
9 pub name: String,
11 pub message: String,
13 js_to_string: String,
14}
15
16impl From<js_sys::Error> for JsError {
17 fn from(error: js_sys::Error) -> Self {
18 JsError {
19 name: String::from(error.name()),
20 message: String::from(error.message()),
21 js_to_string: String::from(error.to_string()),
22 }
23 }
24}
25
26pub struct NotJsError {
28 pub js_value: JsValue,
29 js_to_string: String,
30}
31
32impl fmt::Debug for NotJsError {
33 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34 f.debug_struct("NotJsError")
35 .field("js_value", &self.js_value)
36 .finish()
37 }
38}
39
40impl fmt::Display for NotJsError {
41 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42 f.write_str(&self.js_to_string)
43 }
44}
45
46impl std::error::Error for NotJsError {}
47
48impl TryFrom<JsValue> for JsError {
49 type Error = NotJsError;
50
51 fn try_from(value: JsValue) -> Result<Self, Self::Error> {
52 match value.dyn_into::<js_sys::Error>() {
53 Ok(error) => Ok(JsError::from(error)),
54 Err(js_value) => {
55 let js_to_string = String::from(js_sys::JsString::from(js_value.clone()));
56 Err(NotJsError {
57 js_value,
58 js_to_string,
59 })
60 }
61 }
62 }
63}
64
65impl fmt::Display for JsError {
66 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67 write!(f, "{}", self.js_to_string)
68 }
69}
70
71impl fmt::Debug for JsError {
72 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73 f.debug_struct("JsError")
74 .field("name", &self.name)
75 .field("message", &self.message)
76 .finish()
77 }
78}
79
80impl std::error::Error for JsError {}