cosmwasm_std/errors/
system_error.rs

1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3
4use crate::Binary;
5
6/// SystemError is used for errors inside the VM and is API friendly (i.e. serializable).
7///
8/// This is used on return values for Querier as a nested result: Result<StdResult<T>, SystemError>
9/// The first wrap (SystemError) will trigger if the contract address doesn't exist,
10/// the QueryRequest is malformed, etc. The second wrap will be an error message from
11/// the contract itself.
12///
13/// Such errors are only created by the VM. The error type is defined in the standard library, to ensure
14/// the contract understands the error format without creating a dependency on cosmwasm-vm.
15#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
16#[serde(rename_all = "snake_case")]
17#[non_exhaustive]
18pub enum SystemError {
19    InvalidRequest {
20        error: String,
21        request: Binary,
22    },
23    InvalidResponse {
24        error: String,
25        response: Binary,
26    },
27    NoSuchContract {
28        /// The address that was attempted to query
29        addr: String,
30    },
31    /// A Wasm code was not found.
32    NoSuchCode {
33        /// The code ID that is missing
34        code_id: u64,
35    },
36    Unknown {},
37    UnsupportedRequest {
38        kind: String,
39    },
40}
41
42impl std::error::Error for SystemError {}
43
44impl core::fmt::Display for SystemError {
45    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
46        match self {
47            SystemError::InvalidRequest { error, request } => write!(
48                f,
49                "Cannot parse request: {} in: {}",
50                error,
51                String::from_utf8_lossy(request)
52            ),
53            SystemError::InvalidResponse { error, response } => write!(
54                f,
55                "Cannot parse response: {} in: {}",
56                error,
57                String::from_utf8_lossy(response)
58            ),
59            SystemError::NoSuchContract { addr } => write!(f, "No such contract: {addr}"),
60            SystemError::NoSuchCode { code_id } => write!(f, "No such code: {code_id}"),
61            SystemError::Unknown {} => write!(f, "Unknown system error"),
62            SystemError::UnsupportedRequest { kind } => {
63                write!(f, "Unsupported query type: {kind}")
64            }
65        }
66    }
67}
68
69#[cfg(test)]
70mod tests {
71    use super::*;
72    use crate::{from_json, to_json_vec};
73
74    #[test]
75    fn system_error_no_such_contract_serialization() {
76        let err = SystemError::NoSuchContract {
77            addr: "gibtsnicht".to_string(),
78        };
79
80        // ser
81        let json = to_json_vec(&err).unwrap();
82        assert_eq!(
83            String::from_utf8_lossy(&json),
84            r#"{"no_such_contract":{"addr":"gibtsnicht"}}"#,
85        );
86
87        // de
88        let err: SystemError = from_json(br#"{"no_such_contract":{"addr":"nada"}}"#).unwrap();
89        assert_eq!(
90            err,
91            SystemError::NoSuchContract {
92                addr: "nada".to_string()
93            }
94        );
95    }
96
97    #[test]
98    fn system_error_no_such_code_serialization() {
99        let err = SystemError::NoSuchCode { code_id: 13 };
100
101        // ser
102        let json = to_json_vec(&err).unwrap();
103        assert_eq!(
104            String::from_utf8_lossy(&json),
105            r#"{"no_such_code":{"code_id":13}}"#,
106        );
107
108        // de
109        let err: SystemError = from_json(br#"{"no_such_code":{"code_id":987}}"#).unwrap();
110        assert_eq!(err, SystemError::NoSuchCode { code_id: 987 },);
111    }
112}