indexed_db/
error.rs

1use crate::utils::err_from_event;
2use web_sys::{
3    wasm_bindgen::{JsCast, JsValue},
4    DomException,
5};
6
7/// Type alias for convenience
8pub type Result<T, E> = std::result::Result<T, Error<E>>;
9
10/// Error type for all errors from this crate
11///
12/// The `E` generic argument is used for user-defined error types, eg. when
13/// the user provides a callback.
14#[derive(Clone, Debug, thiserror::Error)]
15#[non_exhaustive]
16pub enum Error<E> {
17    /// Not running in a browser window
18    #[error("Not running in a browser window")]
19    NotInBrowser,
20
21    /// IndexedDB is disabled
22    #[error("IndexedDB is disabled")]
23    IndexedDbDisabled,
24
25    /// Operation is not supported by the browser
26    #[error("Operation is not supported by the browser")]
27    OperationNotSupported,
28
29    /// Operation is not allowed by the user agent
30    #[error("Operation is not allowed by the user agent")]
31    OperationNotAllowed,
32
33    /// Provided key is not valid
34    #[error("Provided key is not valid")]
35    InvalidKey,
36
37    /// Version must not be zero
38    #[error("Version must not be zero")]
39    VersionMustNotBeZero,
40
41    /// Requested version is older than existing version
42    #[error("Requested version is older than existing version")]
43    VersionTooOld,
44
45    /// The requested function cannot be called from this context
46    #[error("The requested function cannot be called from this context")]
47    InvalidCall,
48
49    /// The provided arguments are invalid
50    #[error("The provided arguments are invalid")]
51    InvalidArgument,
52
53    /// Cannot create something that already exists
54    #[error("Cannot create something that already exists")]
55    AlreadyExists,
56
57    /// Cannot change something that does not exists
58    #[error("Cannot change something that does not exists")]
59    DoesNotExist,
60
61    /// Database is closed
62    #[error("Database is closed")]
63    DatabaseIsClosed,
64
65    /// Object store was removed
66    #[error("Object store was removed")]
67    ObjectStoreWasRemoved,
68
69    /// Transaction is read-only
70    #[error("Transaction is read-only")]
71    ReadOnly,
72
73    /// Unable to clone
74    #[error("Unable to clone")]
75    FailedClone,
76
77    /// Invalid range
78    #[error("Invalid range")]
79    InvalidRange,
80
81    /// Cursor finished its range
82    #[error("Cursor finished its range")]
83    CursorCompleted,
84
85    /// User-provided error to pass through `indexed-db` code
86    #[error(transparent)]
87    User(#[from] E),
88}
89
90impl<Err> Error<Err> {
91    pub(crate) fn from_dom_exception(err: DomException) -> Error<Err> {
92        match &err.name() as &str {
93            "NotSupportedError" => crate::Error::OperationNotSupported,
94            "NotAllowedError" => crate::Error::OperationNotAllowed,
95            "VersionError" => crate::Error::VersionTooOld,
96            _ => panic!("Unexpected error: {err:?}"),
97        }
98    }
99
100    pub(crate) fn from_js_value(v: JsValue) -> Error<Err> {
101        let err = v
102            .dyn_into::<web_sys::DomException>()
103            .expect("Trying to parse indexed_db::Error from value that is not a DomException");
104        Error::from_dom_exception(err)
105    }
106
107    pub(crate) fn from_js_event(evt: web_sys::Event) -> Error<Err> {
108        Error::from_dom_exception(err_from_event(evt))
109    }
110}
111
112pub(crate) fn name(v: &JsValue) -> Option<String> {
113    v.dyn_ref::<web_sys::DomException>().map(|v| v.name())
114}