error.rs (1837B)
1 use borsh::maybestd::io::Error as BorshIoError; 2 use std::result::Result as ResultGeneric; 3 4 pub type ContractResult = ResultGeneric<(), ContractError>; 5 6 #[derive(Debug, thiserror::Error)] 7 pub enum ContractError { 8 /// Allows on-chain programs to implement contract-specific error types and 9 /// see them returned by the runtime. A contract-specific error may be any 10 /// type that is represented as or serialized to an u32 inteter. 11 #[error("Custom contract error: {0:#x}")] 12 Custom(u32), 13 14 #[error("Internal error")] 15 Internal, 16 #[error("IO error: {0}")] 17 BorshIoError(String), 18 } 19 20 /// Builtin return values occupy the upper 32 bits 21 const BUILTIN_BIT_SHIFT: usize = 32; 22 macro_rules! to_builtin { 23 ($error:expr) => { 24 ($error as u64) << BUILTIN_BIT_SHIFT 25 }; 26 } 27 28 pub const CUSTOM_ZERO: u64 = to_builtin!(1); 29 pub const INTERNAL_ERROR: u64 = to_builtin!(2); 30 pub const BORSH_IO_ERROR: u64 = to_builtin!(3); 31 32 impl From<ContractError> for u64 { 33 fn from(err: ContractError) -> Self { 34 match err { 35 ContractError::Internal => INTERNAL_ERROR, 36 ContractError::BorshIoError(_) => BORSH_IO_ERROR, 37 ContractError::Custom(error) => { 38 if error == 0 { 39 CUSTOM_ZERO 40 } else { 41 error as u64 42 } 43 } 44 } 45 } 46 } 47 48 impl From<u64> for ContractError { 49 fn from(error: u64) -> Self { 50 match error { 51 CUSTOM_ZERO => Self::Custom(0), 52 INTERNAL_ERROR => Self::Internal, 53 BORSH_IO_ERROR => Self::BorshIoError("Unknown".to_string()), 54 _ => Self::Custom(error as u32), 55 } 56 } 57 } 58 59 impl From<BorshIoError> for ContractError { 60 fn from(error: BorshIoError) -> Self { 61 Self::BorshIoError(format!("{}", error)) 62 } 63 }