Skip to main content

rings_node/
error.rs

1//! A bunch of wrap errors.
2use crate::prelude::rings_core;
3
4/// A wrap `Result` contains custom errors.
5pub type Result<T> = std::result::Result<T, Error>;
6
7/// Errors enum mapping global custom errors.
8/// The error type can be expressed in decimal, where the high decs represent
9/// the error category and the low decs represent the error type.
10#[derive(Debug, thiserror::Error)]
11#[non_exhaustive]
12#[repr(u32)]
13pub enum Error {
14    #[error("Connect remote rpc server failed: {0}.")]
15    RemoteRpcError(String) = 100,
16    #[error("Unknown rpc error.")]
17    UnknownRpcError = 101,
18    #[error("Internal rpc services error: {0}.")]
19    InternalRpcError(#[from] jsonrpc_core::Error) = 102,
20    #[error("Uuid error: {0}")]
21    UuidError(#[from] uuid::Error) = 103,
22    #[error("Connection not found.")]
23    ConnectionNotFound = 203,
24    #[error("Create connection error: {0}.")]
25    NewConnectionError(rings_core::error::Error) = 204,
26    #[error("Close connection error: {0}.")]
27    CloseConnectionError(rings_core::error::Error) = 205,
28    #[error("Invalid connection id.")]
29    InvalidConnectionId = 206,
30    #[error("Create offer info failed: {0}.")]
31    CreateOffer(rings_core::error::Error) = 207,
32    #[error("Answer offer info failed: {0}.")]
33    AnswerOffer(rings_core::error::Error) = 208,
34    #[error("Accept answer info failed: {0}.")]
35    AcceptAnswer(rings_core::error::Error) = 209,
36    #[error("Decode error.")]
37    DecodeError = 300,
38    #[error("Encode error.")]
39    EncodeError = 301,
40    #[error("WASM compile error: {0}")]
41    WasmCompileError(String) = 400,
42    #[error("BackendMessage RwLock Error")]
43    WasmBackendMessageRwLockError = 401,
44    #[error("WASM instantiation error.")]
45    WasmInstantiationError = 402,
46    #[error("WASM export error.")]
47    WasmExportError = 403,
48    #[error("WASM runtime error: {0}")]
49    WasmRuntimeError(String) = 404,
50    #[error("WASM global memory mutex error.")]
51    WasmGlobalMemoryLockError = 405,
52    #[error("WASM failed to load file.")]
53    WasmFailedToLoadFile = 406,
54    #[error("Invalid did: {0}")]
55    InvalidDid(String) = 500,
56    #[error("Invalid method.")]
57    InvalidMethod = 501,
58    #[error("Internal error: {0}.")]
59    InternalError(rings_core::error::Error) = 502,
60    #[error("No Permission")]
61    NoPermission = 504,
62    #[error("Connect error, {0}")]
63    ConnectError(rings_core::error::Error) = 600,
64    #[error("Send message error: {0}")]
65    SendMessage(rings_core::error::Error) = 601,
66    #[error("entry action error: {0}")]
67    EntryError(rings_core::error::Error) = 603,
68    #[error("service register action error: {0}")]
69    ServiceRegisterError(rings_core::error::Error) = 604,
70    #[error("JsError: {0}")]
71    JsError(String) = 700,
72    #[error("Invalid message")]
73    InvalidMessage = 800,
74    #[error("Invalid http request: {0}")]
75    HttpRequestError(String) = 801,
76    #[error("Invalid data")]
77    InvalidData = 802,
78    #[error("Invalid service")]
79    InvalidService = 803,
80    #[error("Invalid address")]
81    InvalidAddress = 804,
82    #[error("Invalid auth data")]
83    InvalidAuthData = 805,
84    #[error("invalid headers")]
85    InvalidHeaders = 806,
86    #[error("Storage Error: {0}")]
87    Storage(rings_core::error::Error) = 807,
88    #[error("Swarm Error: {0}")]
89    Swarm(rings_core::error::Error) = 808,
90    #[error("Invalid logging level: {0}")]
91    InvalidLoggingLevel(String) = 809,
92    #[error("Invalid WebRTC UDP port range: {0}")]
93    InvalidWebrtcUdpPortRange(#[from] rings_transport::webrtc_config::WebrtcUdpPortRangeError) =
94        810,
95    #[error("Both webrtc_udp_port_min and webrtc_udp_port_max must be set together: min={min:?}, max={max:?}")]
96    IncompleteWebrtcUdpPortRange { min: Option<u16>, max: Option<u16> } = 811,
97    #[error("Create File Error: {0}")]
98    CreateFileError(String) = 900,
99    #[error("Open File Error: {0}")]
100    OpenFileError(String) = 901,
101    #[error("Acquire lock failed")]
102    Lock = 902,
103    #[error("Cannot find home directory")]
104    HomeDirError = 903,
105    #[error("Cannot find parent directory")]
106    ParentDirError = 904,
107    #[error("Path is not valid UTF-8: {0}")]
108    PathUtf8Error(String) = 905,
109    #[error("Serde json error: {0}")]
110    SerdeJsonError(#[from] serde_json::Error) = 1000,
111    #[error("Serde yaml error: {0}")]
112    SerdeYamlError(#[from] serde_yaml::Error) = 1001,
113    #[error("verify error: {0}")]
114    VerifyError(String) = 1002,
115    #[error("Core error: {0}")]
116    CoreError(#[from] rings_core::error::Error) = 1102,
117    #[error("External singer error: {0}")]
118    ExternalError(String) = 1202,
119    #[error("An error indicating that an interior nul byte was found: {0}")]
120    FFINulError(#[from] std::ffi::NulError) = 1203,
121    #[error("Failed to convert CStr to String: {0}")]
122    FFICStrError(#[from] std::str::Utf8Error) = 1204,
123    #[error("An error indicating that a ptr is null")]
124    FFINulPtrError = 1205,
125    #[error("Failed to convert bytes to String: {0}")]
126    FFIFromUtf8Error(#[from] std::string::FromUtf8Error) = 1206,
127    #[cfg(feature = "snark")]
128    #[error("Snark error: {0}")]
129    RingsSNARKError(#[from] rings_snark::error::Error) = 1400,
130    #[error("Snark curve not match")]
131    SNARKCurveNotMatch() = 1401,
132    #[error("Snark handle message error: {0}")]
133    SNARKHandleMessage(String) = 1402,
134    #[error("Wrong field, should be {0}")]
135    SNARKWrongField(String) = 1403,
136    #[cfg(feature = "browser")]
137    #[error("range error when covering js_sys::BigInt to PrimeField: {0}")]
138    SNARKFFRangeError(String) = 1404,
139    #[cfg(feature = "browser")]
140    #[error("Failed to load bigint to repr string, it's empty")]
141    SNARKBigIntValueEmpty() = 1405,
142    #[error("Failed to load string to PrimeField")]
143    FailedToLoadFF() = 1406,
144    #[error("Extend Backend Error {0}")]
145    BackendError(String) = 1501,
146    #[error("Extension error: {0}")]
147    ExtensionError(String) = 1502,
148}
149
150impl Error {
151    fn discriminant(&self) -> u32 {
152        // SAFETY: Because `Self` is marked `repr(u32)`, its layout is a `repr(C)` `union`
153        // between `repr(C)` structs, each of which has the `u32` discriminant as its first
154        // field, so we can read the discriminant without offsetting the pointer.
155        // This code is copy from
156        // ref: https://doc.rust-lang.org/std/mem/fn.discriminant.html
157        // And we modify it from [u8] to [u32], this is work because
158        // repr(C) is equivalent to one of repr(u*) (see the next section) for
159        // fieldless enums.
160        // ref: https://doc.rust-lang.org/nomicon/other-reprs.html
161        unsafe { *<*const _>::from(self).cast::<u32>() }
162    }
163
164    pub fn code(&self) -> u32 {
165        self.discriminant()
166    }
167}
168
169impl From<Error> for jsonrpc_core::Error {
170    fn from(e: Error) -> Self {
171        Self {
172            code: jsonrpc_core::ErrorCode::ServerError(e.code().into()),
173            message: e.to_string(),
174            data: None,
175        }
176    }
177}
178
179impl From<rings_rpc::error::Error> for Error {
180    fn from(e: rings_rpc::error::Error) -> Self {
181        match e {
182            rings_rpc::error::Error::InvalidMethod => Error::InvalidMethod,
183            rings_rpc::error::Error::RpcError(v) => Error::RemoteRpcError(v.to_string()),
184            rings_rpc::error::Error::InvalidSignature => Error::InvalidData,
185            rings_rpc::error::Error::InvalidHeaders => Error::InvalidHeaders,
186            _ => Error::UnknownRpcError,
187        }
188    }
189}
190
191#[cfg(feature = "browser")]
192impl From<Error> for wasm_bindgen::JsValue {
193    fn from(err: Error) -> Self {
194        wasm_bindgen::JsValue::from_str(&err.to_string())
195    }
196}
197
198#[cfg(test)]
199mod tests {
200    use super::*;
201    #[test]
202    fn test_error_code() {
203        let err = Error::RemoteRpcError("Test".to_string());
204        assert_eq!(err.code(), 100);
205    }
206}