1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
use std::sync::PoisonError;
use thiserror::Error;
use wasm_bindgen::JsValue;
use workflow_core::channel::{RecvError, TrySendError};
use workflow_core::id::Id;

#[derive(Error, Debug)]
pub enum Error {
    #[error("Error: {0}")]
    Custom(String),

    #[error("Callback Error: {0}")]
    CallbackError(#[from] workflow_wasm::callback::CallbackError),

    #[error("I/O error: {0}")]
    IO(#[from] std::io::Error),

    #[error("NW error: {0}")]
    NW(#[from] nw_sys::error::Error),

    #[error("Error: {0}")]
    JsValue(String),

    #[error("Poison Error: {0}")]
    PoisonError(String),

    #[error("Error: `window.global` object not found")]
    GlobalObjectNotFound,

    #[error("IPC Error: target window `{0}` not found")]
    IpcTargetNotFound(Id),

    #[error("Serde WASM bindgen ser/deser error: {0}")]
    SerdeWasmBindgen(#[from] serde_wasm_bindgen::Error),

    #[error("Unknown broadcast message kind")]
    UnknownBroadcastMessageKind,

    #[error("Error parsing id: {0}")]
    Id(#[from] workflow_core::id::Error),

    #[error("Malformed Ctl message")]
    MalformedCtl,

    #[error("IPC channel send error")]
    ChannelSendError,

    #[error("IPC channel receive error")]
    ChannelRecvError,

    #[error("Broadcast data is not an object")]
    BroadcastDataNotObject,

    #[error(transparent)]
    Wasm(#[from] workflow_wasm::error::Error),

    #[error(transparent)]
    Ipc(#[from] crate::ipc::error::Error),
    // #[error(transparent)]
    // IpcResponse(#[from] crate::ipc::error::ResponseError),
}

impl From<String> for Error {
    fn from(v: String) -> Self {
        Self::Custom(v)
    }
}

impl From<&str> for Error {
    fn from(v: &str) -> Self {
        Self::Custom(v.to_string())
    }
}

impl From<JsValue> for Error {
    fn from(v: JsValue) -> Self {
        Self::JsValue(format!("{v:?}"))
    }
}

impl<T> From<PoisonError<T>> for Error
where
    T: std::fmt::Debug,
{
    fn from(err: PoisonError<T>) -> Error {
        Error::PoisonError(format!("{err:?}"))
    }
}

impl From<Error> for JsValue {
    fn from(err: Error) -> JsValue {
        let s: String = err.to_string();
        JsValue::from_str(&s)
    }
}

impl<T> From<TrySendError<T>> for Error {
    fn from(_: TrySendError<T>) -> Self {
        Error::ChannelSendError
    }
}

impl From<RecvError> for Error {
    fn from(_: RecvError) -> Self {
        Error::ChannelRecvError
    }
}