oasis_runtime_sdk/
error.rs1pub use oasis_core_runtime::types::Error as RuntimeError;
3
4use crate::{dispatcher, module::CallResult};
5
6pub trait Error: std::error::Error {
30 fn module_name(&self) -> &str;
32
33 fn code(&self) -> u32;
35
36 fn into_call_result(self) -> CallResult
38 where
39 Self: Sized,
40 {
41 match self.into_abort() {
42 Ok(err) => CallResult::Aborted(err),
43 Err(failed) => CallResult::Failed {
44 module: failed.module_name().to_owned(),
45 code: failed.code(),
46 message: failed.to_string(),
47 },
48 }
49 }
50
51 fn into_abort(self) -> Result<dispatcher::Error, Self>
54 where
55 Self: Sized,
56 {
57 Err(self)
58 }
59}
60
61impl Error for std::convert::Infallible {
62 fn module_name(&self) -> &str {
63 "(none)"
64 }
65
66 fn code(&self) -> u32 {
67 Default::default()
68 }
69}
70
71#[cfg(test)]
72mod test {
73 use super::*;
74
75 const MODULE_NAME_1: &str = "test1";
76 const MODULE_NAME_2: &str = "test2";
77
78 #[derive(thiserror::Error, Debug, oasis_runtime_sdk_macros::Error)]
79 #[sdk_error(module_name = "MODULE_NAME_1")]
80 enum ChildError {
81 #[error("first error")]
82 #[sdk_error(code = 1)]
83 Error1,
84
85 #[error("second error")]
86 #[sdk_error(code = 2)]
87 Error2,
88 }
89
90 #[derive(thiserror::Error, Debug, oasis_runtime_sdk_macros::Error)]
91 #[sdk_error(module_name = "MODULE_NAME_2")]
92 enum ParentError {
93 #[error("first error")]
94 #[sdk_error(code = 1)]
95 NotForwarded(#[source] ChildError),
96
97 #[error("nested error")]
98 #[sdk_error(transparent)]
99 Nested(#[source] ChildError),
100 }
101
102 #[derive(thiserror::Error, Debug, oasis_runtime_sdk_macros::Error)]
103 enum ParentParentError {
104 #[error("nested nested error")]
105 #[sdk_error(transparent)]
106 Nested(#[source] ParentError),
107 }
108
109 #[test]
110 fn test_error_sources_1() {
111 let err = ParentError::Nested(ChildError::Error1);
112 let result = err.into_call_result();
113
114 match result {
115 CallResult::Failed {
116 module,
117 code,
118 message: _,
119 } => {
120 assert_eq!(module, "test1");
121 assert_eq!(code, 1);
122 }
123 _ => panic!("expected failed result, got: {:?}", result),
124 }
125
126 let err = ParentError::Nested(ChildError::Error2);
127 let result = err.into_call_result();
128
129 match result {
130 CallResult::Failed {
131 module,
132 code,
133 message: _,
134 } => {
135 assert_eq!(module, "test1");
136 assert_eq!(code, 2);
137 }
138 _ => panic!("expected failed result, got: {:?}", result),
139 }
140 }
141
142 #[test]
143 fn test_error_sources_2() {
144 let err = ParentError::NotForwarded(ChildError::Error1);
145 let result = err.into_call_result();
146
147 match result {
148 CallResult::Failed {
149 module,
150 code,
151 message: _,
152 } => {
153 assert_eq!(module, "test2");
154 assert_eq!(code, 1);
155 }
156 _ => panic!("expected failed result, got: {:?}", result),
157 }
158
159 let err = ParentError::NotForwarded(ChildError::Error2);
160 let result = err.into_call_result();
161
162 match result {
163 CallResult::Failed {
164 module,
165 code,
166 message: _,
167 } => {
168 assert_eq!(module, "test2");
169 assert_eq!(code, 1);
170 }
171 _ => panic!("expected failed result, got: {:?}", result),
172 }
173 }
174
175 #[test]
176 fn test_error_sources_3() {
177 let err = ParentParentError::Nested(ParentError::Nested(ChildError::Error1));
178 let result = err.into_call_result();
179
180 match result {
181 CallResult::Failed {
182 module,
183 code,
184 message: _,
185 } => {
186 assert_eq!(module, "test1");
187 assert_eq!(code, 1);
188 }
189 _ => panic!("expected failed result, got: {:?}", result),
190 }
191 }
192}