1use core::any::Any;
2
3use casper_types::bytesrepr::Error as BytesReprError;
4use casper_types::{CLType, CLValueError};
5
6use crate::arithmetic::ArithmeticsError;
7use crate::prelude::*;
8use crate::VmError::Serialization;
9
10#[repr(u16)]
12#[derive(Clone, Debug, PartialEq)]
13pub enum OdraError {
14 ExecutionError(ExecutionError),
16 VmError(VmError)
18}
19
20impl OdraError {
21 pub fn code(&self) -> u16 {
23 match self {
24 OdraError::ExecutionError(e) => e.code(),
25 OdraError::VmError(_e) => 0
26 }
27 }
28
29 pub fn user(code: u16) -> Self {
31 if code >= ExecutionError::UserErrorTooHigh.code() {
32 ExecutionError::UserErrorTooHigh.into()
33 } else {
34 ExecutionError::User(code).into()
35 }
36 }
37}
38
39impl From<ArithmeticsError> for ExecutionError {
40 fn from(error: ArithmeticsError) -> Self {
41 match error {
42 ArithmeticsError::AdditionOverflow => Self::AdditionOverflow,
43 ArithmeticsError::SubtractingOverflow => Self::SubtractionOverflow
44 }
45 }
46}
47
48impl From<ArithmeticsError> for OdraError {
49 fn from(error: ArithmeticsError) -> Self {
50 Into::<ExecutionError>::into(error).into()
51 }
52}
53
54impl From<Box<dyn Any + Send>> for OdraError {
55 fn from(_: Box<dyn Any + Send>) -> Self {
56 OdraError::VmError(VmError::Panic)
57 }
58}
59
60impl From<casper_types::bytesrepr::Error> for ExecutionError {
61 fn from(error: casper_types::bytesrepr::Error) -> Self {
62 match error {
63 casper_types::bytesrepr::Error::EarlyEndOfStream => Self::EarlyEndOfStream,
64 casper_types::bytesrepr::Error::Formatting => Self::Formatting,
65 casper_types::bytesrepr::Error::LeftOverBytes => Self::LeftOverBytes,
66 casper_types::bytesrepr::Error::OutOfMemory => Self::OutOfMemory,
67 casper_types::bytesrepr::Error::NotRepresentable => Self::NotRepresentable,
68 casper_types::bytesrepr::Error::ExceededRecursionDepth => Self::ExceededRecursionDepth,
69 _ => Self::Formatting
70 }
71 }
72}
73
74#[repr(u16)]
84#[derive(Clone, Copy, Debug, PartialEq)]
85pub enum ExecutionError {
86 UnwrapError = 1,
88 UnexpectedError = 2,
90 AdditionOverflow = 100,
92 SubtractionOverflow = 101,
94 NonPayable = 102,
96 TransferToContract = 103,
98 ReentrantCall = 104,
100 ContractAlreadyInstalled = 105,
102 UnknownConstructor = 106,
104 NativeTransferError = 107,
106 IndexOutOfBounds = 108,
108 ZeroAddress = 109,
110 AddressCreationFailed = 110,
112 EarlyEndOfStream = 111,
114 Formatting = 112,
116 LeftOverBytes = 113,
118 OutOfMemory = 114,
120 NotRepresentable = 115,
122 ExceededRecursionDepth = 116,
124 KeyNotFound = 117,
126 CouldNotDeserializeSignature = 118,
128 TypeMismatch = 119,
130 CouldNotSignMessage = 120,
132 EmptyDictionaryName = 121,
134 MissingArg = 122,
136 MissingAddress = 123,
138 OutOfGas = 124,
140 MaxUserError = 64535,
142 UserErrorTooHigh = 64536,
144 User(u16)
146}
147
148impl ExecutionError {
149 pub fn code(&self) -> u16 {
151 unsafe {
152 match self {
153 ExecutionError::User(code) => *code,
154 ExecutionError::MaxUserError => 64535,
155 ExecutionError::UserErrorTooHigh => 64536,
156 _ => ExecutionError::UserErrorTooHigh.code() + *(self as *const Self as *const u16)
157 }
158 }
159 }
160}
161
162impl From<ExecutionError> for OdraError {
163 fn from(error: ExecutionError) -> Self {
164 Self::ExecutionError(error)
165 }
166}
167
168#[derive(Clone, Debug, PartialEq, Eq)]
170pub enum VmError {
171 Serialization,
173 Deserialization,
175 BalanceExceeded,
177 NoSuchMethod(String),
179 InvalidContractAddress,
181 InvalidContext,
183 TypeMismatch {
185 expected: CLType,
187 found: CLType
189 },
190 Other(String),
192 Panic
194}
195
196pub enum CollectionError {
198 IndexOutOfBounds
200}
201
202impl From<CollectionError> for ExecutionError {
203 fn from(error: CollectionError) -> Self {
204 match error {
205 CollectionError::IndexOutOfBounds => Self::IndexOutOfBounds
206 }
207 }
208}
209
210impl From<CollectionError> for OdraError {
211 fn from(error: CollectionError) -> Self {
212 Into::<ExecutionError>::into(error).into()
213 }
214}
215
216#[derive(Clone, Debug, PartialEq)]
218pub enum AddressError {
219 ZeroAddress,
221 AddressCreationError
223}
224
225impl From<AddressError> for ExecutionError {
226 fn from(error: AddressError) -> Self {
227 match error {
228 AddressError::ZeroAddress => Self::ZeroAddress,
229 AddressError::AddressCreationError => Self::AddressCreationFailed
230 }
231 }
232}
233
234impl From<AddressError> for OdraError {
235 fn from(error: AddressError) -> Self {
236 Into::<ExecutionError>::into(error).into()
237 }
238}
239
240#[derive(Debug, PartialEq, Eq, PartialOrd)]
242pub enum EventError {
243 UnexpectedType(String),
245 IndexOutOfBounds,
247 Formatting,
249 Parsing,
251 CouldntExtractName,
253 CouldntExtractEventData
255}
256
257pub type OdraResult<T> = Result<T, OdraError>;
259
260impl From<CLValueError> for OdraError {
261 fn from(error: CLValueError) -> Self {
262 match error {
263 CLValueError::Serialization(_) => OdraError::VmError(Serialization),
264 CLValueError::Type(cl_type_mismatch) => OdraError::VmError(VmError::TypeMismatch {
265 expected: cl_type_mismatch.expected.clone(),
266 found: cl_type_mismatch.found.clone()
267 })
268 }
269 }
270}
271
272impl From<BytesReprError> for OdraError {
273 fn from(error: BytesReprError) -> Self {
274 match error {
275 BytesReprError::EarlyEndOfStream => ExecutionError::EarlyEndOfStream,
276 BytesReprError::Formatting => ExecutionError::Formatting,
277 BytesReprError::LeftOverBytes => ExecutionError::LeftOverBytes,
278 BytesReprError::OutOfMemory => ExecutionError::OutOfMemory,
279 BytesReprError::NotRepresentable => ExecutionError::NotRepresentable,
280 BytesReprError::ExceededRecursionDepth => ExecutionError::ExceededRecursionDepth,
281 _ => ExecutionError::Formatting
282 }
283 .into()
284 }
285}