diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 00000000..29d8f789 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "koii-contract-error-handling" +version = "0.1.0" +edition = "2021" + +[dependencies] +thiserror = "1.0" + +[dev-dependencies] +rstest = "0.18.2" \ No newline at end of file diff --git a/src/errors/mod.rs b/src/errors/mod.rs new file mode 100644 index 00000000..b5b63591 --- /dev/null +++ b/src/errors/mod.rs @@ -0,0 +1,74 @@ +use thiserror::Error; + +/// Comprehensive error enum for smart contract operations +#[derive(Error, Debug, Clone, PartialEq)] +pub enum ContractError { + /// Generic initialization error + #[error("Initialization failed: {0}")] + InitializationError(String), + + /// Token transfer validation error + #[error("Invalid token transfer: {0}")] + TokenTransferError(String), + + /// Authorization and permission-related errors + #[error("Authorization failed: {0}")] + AuthorizationError(String), + + /// Validation errors for input parameters + #[error("Invalid input: {0}")] + ValidationError(String), + + /// Resource not found errors + #[error("Resource not found: {0}")] + ResourceNotFoundError(String), + + /// Arithmetic or computational errors + #[error("Computation error: {0}")] + ComputationError(String), + + /// Generic unexpected error + #[error("Unexpected error occurred: {0}")] + UnexpectedError(String), +} + +/// Result type using our custom ContractError +pub type ContractResult = Result; + +/// Utility functions for error handling +impl ContractError { + /// Create a new initialization error + pub fn initialization(message: impl ToString) -> Self { + ContractError::InitializationError(message.to_string()) + } + + /// Create a new token transfer error + pub fn token_transfer(message: impl ToString) -> Self { + ContractError::TokenTransferError(message.to_string()) + } + + /// Create a new authorization error + pub fn authorization(message: impl ToString) -> Self { + ContractError::AuthorizationError(message.to_string()) + } + + /// Create a new validation error + pub fn validation(message: impl ToString) -> Self { + ContractError::ValidationError(message.to_string()) + } + + /// Create a new resource not found error + pub fn resource_not_found(message: impl ToString) -> Self { + ContractError::ResourceNotFoundError(message.to_string()) + } + + /// Create a new computation error + pub fn computation(message: impl ToString) -> Self { + ContractError::ComputationError(message.to_string()) + } + + /// Create a new unexpected error + pub fn unexpected(message: impl ToString) -> Self { + ContractError::UnexpectedError(message.to_string()) + } +} \ No newline at end of file diff --git a/tests/error_handling_tests.rs b/tests/error_handling_tests.rs new file mode 100644 index 00000000..f7209de8 --- /dev/null +++ b/tests/error_handling_tests.rs @@ -0,0 +1,70 @@ +use std::error::Error; +use std::fmt::Display; + +mod errors { + pub(crate) use crate::src::errors::{ContractError, ContractResult}; +} + +#[test] +fn test_error_creation() { + // Test initialization error + let init_error = errors::ContractError::initialization("Database connection failed"); + assert_eq!( + init_error.to_string(), + "Initialization failed: Database connection failed" + ); + + // Test token transfer error + let transfer_error = errors::ContractError::token_transfer("Insufficient balance"); + assert_eq!( + transfer_error.to_string(), + "Invalid token transfer: Insufficient balance" + ); + + // Test authorization error + let auth_error = errors::ContractError::authorization("Permission denied"); + assert_eq!( + auth_error.to_string(), + "Authorization failed: Permission denied" + ); +} + +#[test] +fn test_error_conversion() { + // Test validation error + let validation_error = errors::ContractError::validation("Invalid input format"); + assert_eq!( + validation_error.to_string(), + "Invalid input: Invalid input format" + ); + + // Test resource not found error + let not_found_error = errors::ContractError::resource_not_found("User account"); + assert_eq!( + not_found_error.to_string(), + "Resource not found: User account" + ); +} + +#[test] +fn test_error_propagation() { + fn simulate_operation() -> errors::ContractResult<()> { + Err(errors::ContractError::computation("Math overflow")) + } + + let result = simulate_operation(); + assert!(result.is_err()); + + if let Err(err) = result { + assert_eq!(err.to_string(), "Computation error: Math overflow"); + } +} + +#[test] +fn test_unexpected_error() { + let unexpected = errors::ContractError::unexpected("Unhandled system error"); + assert_eq!( + unexpected.to_string(), + "Unexpected error occurred: Unhandled system error" + ); +} \ No newline at end of file