Skip to main content

workflow_nw/
error.rs

1use std::sync::PoisonError;
2use thiserror::Error;
3use wasm_bindgen::JsValue;
4use workflow_core::channel::{RecvError, TrySendError};
5use workflow_core::id::Id;
6
7/// Errors produced by the `workflow-nw` crate.
8#[derive(Error, Debug)]
9pub enum Error {
10    /// A custom, free-form error message.
11    #[error("Error: {0}")]
12    Custom(String),
13
14    /// Error originating from a WASM callback invocation.
15    #[error("Callback Error: {0}")]
16    CallbackError(#[from] workflow_wasm::callback::CallbackError),
17
18    /// Underlying I/O error.
19    #[error("I/O error: {0}")]
20    IO(#[from] std::io::Error),
21
22    /// Error returned from the `nw_sys` NW.js bindings.
23    #[error("NW error: {0}")]
24    NW(#[from] nw_sys::error::Error),
25
26    /// A JavaScript exception captured as a string.
27    #[error("Error: {0}")]
28    JsValue(String),
29
30    /// A mutex/lock was poisoned.
31    #[error("Poison Error: {0}")]
32    PoisonError(String),
33
34    /// The JavaScript `window.global` object could not be found.
35    #[error("Error: `window.global` object not found")]
36    GlobalObjectNotFound,
37
38    /// No IPC target window matching the given id was found.
39    #[error("IPC Error: target window `{0}` not found")]
40    IpcTargetNotFound(Id),
41
42    /// Serialization/deserialization error via `serde-wasm-bindgen`.
43    #[error("Serde WASM bindgen ser/deser error: {0}")]
44    SerdeWasmBindgen(#[from] serde_wasm_bindgen::Error),
45
46    /// A received broadcast message had an unrecognized kind.
47    #[error("Unknown broadcast message kind")]
48    UnknownBroadcastMessageKind,
49
50    /// Error parsing an identifier.
51    #[error("Error parsing id: {0}")]
52    Id(#[from] workflow_core::id::Error),
53
54    /// A control (`Ctl`) message could not be parsed.
55    #[error("Malformed Ctl message")]
56    MalformedCtl,
57
58    /// Failed to send a message over an IPC channel.
59    #[error("IPC channel send error")]
60    ChannelSendError,
61
62    /// Failed to receive a message from an IPC channel.
63    #[error("IPC channel receive error")]
64    ChannelRecvError,
65
66    /// Broadcast payload was expected to be a JavaScript object but was not.
67    #[error("Broadcast data is not an object")]
68    BroadcastDataNotObject,
69
70    /// Error originating from the `workflow-wasm` crate.
71    #[error(transparent)]
72    Wasm(#[from] workflow_wasm::error::Error),
73
74    /// Error originating from the IPC subsystem.
75    #[error(transparent)]
76    Ipc(#[from] crate::ipc::error::Error),
77    // #[error(transparent)]
78    // IpcResponse(#[from] crate::ipc::error::ResponseError),
79}
80
81impl From<String> for Error {
82    fn from(v: String) -> Self {
83        Self::Custom(v)
84    }
85}
86
87impl From<&str> for Error {
88    fn from(v: &str) -> Self {
89        Self::Custom(v.to_string())
90    }
91}
92
93impl From<JsValue> for Error {
94    fn from(v: JsValue) -> Self {
95        Self::JsValue(format!("{v:?}"))
96    }
97}
98
99impl<T> From<PoisonError<T>> for Error
100where
101    T: std::fmt::Debug,
102{
103    fn from(err: PoisonError<T>) -> Error {
104        Error::PoisonError(format!("{err:?}"))
105    }
106}
107
108impl From<Error> for JsValue {
109    fn from(err: Error) -> JsValue {
110        let s: String = err.to_string();
111        JsValue::from_str(&s)
112    }
113}
114
115impl<T> From<TrySendError<T>> for Error {
116    fn from(_: TrySendError<T>) -> Self {
117        Error::ChannelSendError
118    }
119}
120
121impl From<RecvError> for Error {
122    fn from(_: RecvError) -> Self {
123        Error::ChannelRecvError
124    }
125}