Skip to main content

workflow_store/
error.rs

1//!
2//!  Errors produced by this crate.
3//!
4
5use base64::DecodeError;
6use thiserror::Error;
7use wasm_bindgen::prelude::*;
8use workflow_wasm::jserror::*;
9
10/// Errors produced by the `workflow-store` crate.
11#[derive(Error, Debug)]
12pub enum Error {
13    /// A custom, free-form error message.
14    #[error("{0}")]
15    Custom(String),
16
17    /// An underlying file system I/O error.
18    #[error("I/O error: {0}")]
19    IoError(#[from] std::io::Error),
20
21    /// An error originating from the Chrome extension storage backend.
22    #[error("Chrome error: {0}")]
23    ChromeError(#[from] workflow_chrome::error::Error),
24
25    // #[error("JavaScript error: {0:?}")]
26    // JsValue(Sendable<JsValue>),
27    /// An error captured from a JavaScript exception or rejected promise.
28    #[error("{0}")]
29    JsValue(JsErrorData),
30
31    /// A Base64 string could not be decoded.
32    #[error("Base64 decode error: {0}")]
33    DecodeError(DecodeError),
34
35    /// The requested file or storage key does not exist.
36    #[error("Not found: {0}")]
37    NotFound(String),
38
39    /// The stored data was expected to be a UTF-8 string but is not.
40    #[error("Not a text data: {0}")]
41    DataIsNotAString(String),
42
43    /// The stored data was expected to be a binary buffer but is not.
44    #[error("Not a buffer data: {0}")]
45    DataIsNotABuffer(String),
46
47    /// A JSON serialization or deserialization error.
48    #[error(transparent)]
49    SerdeJson(#[from] serde_json::Error),
50
51    /// The supplied path is malformed or otherwise invalid.
52    #[error("invalid path: {0}")]
53    InvalidPath(String),
54
55    /// The user's home directory could not be determined.
56    #[error("Unable to obtain user home directory")]
57    HomeDir(String),
58
59    /// File metadata is unavailable.
60    #[error("No file metadata")]
61    Metadata,
62
63    /// A hex encoding or decoding error.
64    #[error(transparent)]
65    FasterHex(#[from] faster_hex::Error),
66
67    /// The requested operation is not supported in the current environment.
68    #[error("This operation is not supported")]
69    NotSupported,
70}
71
72impl From<Error> for JsValue {
73    fn from(err: Error) -> Self {
74        match err {
75            Error::JsValue(js_err) => js_err.into(),
76            _ => err.into(),
77        }
78    }
79}
80
81// impl From<Error> for JsErrorData {
82//     fn from(err: Error) -> Self {
83//         match err {
84//             Error::JsValue(js_err) => js_err.into(),
85//             _ => err.into(),
86//         }
87//     }
88// }
89
90impl From<JsValue> for Error {
91    fn from(error: JsValue) -> Error {
92        Error::JsValue(error.into())
93    }
94}
95
96impl From<JsErrorData> for Error {
97    fn from(error: JsErrorData) -> Error {
98        Error::JsValue(error)
99    }
100}
101
102impl From<DecodeError> for Error {
103    fn from(error: DecodeError) -> Error {
104        Error::DecodeError(error)
105    }
106}
107
108impl From<String> for Error {
109    fn from(error: String) -> Error {
110        Error::Custom(error)
111    }
112}
113
114impl Error {
115    /// Returns the error code carried by an underlying JavaScript error,
116    /// or `None` for error variants that do not have one.
117    pub fn code(&self) -> Option<&str> {
118        match self {
119            Error::JsValue(js_err) => js_err.code().as_deref(),
120            _ => None,
121        }
122    }
123}