tsdk: Clean up errors. - wasm-runtime - A wasm runtime (HTM) git clone https://git.parazyd.org/wasm-runtime (DIR) Log (DIR) Files (DIR) Refs (DIR) README --- (DIR) commit 5f8ad66aa984f882f4c2d8926c9e15e26f6d5825 (DIR) parent e4fae9954d20225831248af32972253a3577d25f (HTM) Author: parazyd <parazyd@dyne.org> Date: Tue, 8 Mar 2022 23:32:59 +0100 sdk: Clean up errors. Diffstat: M drk-sdk/Cargo.toml | 1 + M drk-sdk/src/error.rs | 59 ++++++++++++++++++++----------- 2 files changed, 39 insertions(+), 21 deletions(-) --- (DIR) diff --git a/drk-sdk/Cargo.toml b/drk-sdk/Cargo.toml t@@ -4,4 +4,5 @@ version = "0.1.0" edition = "2021" [dependencies] +borsh = "0.9.3" thiserror = "1.0.30" (DIR) diff --git a/drk-sdk/src/error.rs b/drk-sdk/src/error.rs t@@ -1,51 +1,68 @@ +use borsh::maybestd::io::Error as BorshIoError; use std::result::Result as ResultGeneric; pub type ContractResult = ResultGeneric<(), ContractError>; #[derive(Debug, thiserror::Error)] -#[repr(C)] pub enum ContractError { + /// Allows on-chain programs to implement contract-specific error types and + /// see them returned by the runtime. A contract-specific error may be any + /// type that is represented as or serialized to an u32 inteter. + #[error("Custom contract error: {0:#x}")] + Custom(u32), + #[error("Internal error")] Internal, - #[error("Out of memory")] OutOfMemory, + #[error("IO error: {0}")] + BorshIoError(String), +} - #[error("IO error")] - Io, - - #[error("Custom contract error: {0:#x}")] - Custom(u32), +/// Builtin return values occupy the upper 32 bits +const BUILTIN_BIT_SHIFT: usize = 32; +macro_rules! to_builtin { + ($error:expr) => { + ($error as u64) << BUILTIN_BIT_SHIFT + }; } -pub const INTERNAL_ERROR: u64 = 1; -pub const OUT_OF_MEMORY: u64 = 2; -pub const IO_ERROR: u64 = 3; +pub const CUSTOM_ZERO: u64 = to_builtin!(1); +pub const INTERNAL_ERROR: u64 = to_builtin!(2); +pub const OUT_OF_MEMORY: u64 = to_builtin!(3); +pub const BORSH_IO_ERROR: u64 = to_builtin!(4); impl From<ContractError> for u64 { fn from(err: ContractError) -> Self { match err { ContractError::Internal => INTERNAL_ERROR, ContractError::OutOfMemory => OUT_OF_MEMORY, - ContractError::Io => IO_ERROR, - ContractError::Custom(e) => e.into(), + ContractError::BorshIoError(_) => BORSH_IO_ERROR, + ContractError::Custom(error) => { + if error == 0 { + CUSTOM_ZERO + } else { + error as u64 + } + } } } } impl From<u64> for ContractError { - fn from(err: u64) -> Self { - match err { - INTERNAL_ERROR => ContractError::Internal, - OUT_OF_MEMORY => ContractError::OutOfMemory, - IO_ERROR => ContractError::Io, - e => ContractError::Custom(e.try_into().unwrap()), + fn from(error: u64) -> Self { + match error { + CUSTOM_ZERO => Self::Custom(0), + INTERNAL_ERROR => Self::Internal, + OUT_OF_MEMORY => Self::OutOfMemory, + BORSH_IO_ERROR => Self::BorshIoError("Unknown".to_string()), + _ => Self::Custom(error as u32), } } } -impl From<std::io::Error> for ContractError { - fn from(_: std::io::Error) -> Self { - Self::Io +impl From<BorshIoError> for ContractError { + fn from(error: BorshIoError) -> Self { + Self::BorshIoError(format!("{}", error)) } }