cosmwasm_std/errors/
system_error.rs

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