This guide provides a comprehensive step-by-step process to verify that the consistent error handling implementation (#364) has been successfully completed across the TeachLink smart contract.
cd contracts/teachlink
./scripts/clean.sh --deepExpected Result: Build artifacts are removed successfully.
cargo build --release --target wasm32-unknown-unknown -p teachlink-contractExpected Result:
- Build completes WITHOUT errors
- No warnings about
unwrap(),panic!, orexpect()in production code - WASM file generated at:
target/wasm32-unknown-unknown/release/teachlink_contract.wasm
Verification Checklist:
- No compilation errors
- No new warnings introduced
- WASM file exists and is valid
# Check for unwrap() in production code
grep -r "\.unwrap()" contracts/teachlink/src/ --include="*.rs" | grep -v "#\[cfg(test)\]" | grep -v "//.*unwrap" | grep -v "test/"Expected Result:
- Only entries showing
.unwrap_or()with defaults (acceptable) - No
.unwrap()without fallback - No entries from production code paths
Verification: If any .unwrap() found in production code, FAIL.
# Check for panic! and assert! in production code
grep -rE "panic!|assert!|expect\(" contracts/teachlink/src/ --include="*.rs" | grep -v "#\[cfg(test)\]" | grep -v "//.*" | grep -v "test/"Expected Result:
- No matches in production code
assert!()only in test code (#[cfg(test)])panic!()only in test code or authorizationexpect()only in test code
Verification: If panic/assert found in production paths, FAIL.
# Check that error-prone functions return Result
grep -rE "pub fn|pub async fn" contracts/teachlink/src/[^t]*.rs | \
grep -E "(analytics|access_control|reputation|bridge)" --include="*.rs"Expected Result: Functions that can fail should return Result<T, E>:
update_participation: Result<(), ReputationError>update_course_progress: Result<(), ReputationError>rate_contribution: Result<(), ReputationError>get_top_chains_by_volume: Result<Vec<_>, AnalyticsError>get_top_chains_by_volume_bounded: Result<Vec<_>, AnalyticsError>check_role: Result<(), AccessControlError>get_token: Result<Address, BridgeError>get_admin: Result<Address, BridgeError>
grep -E "#\[contracterror\]|pub enum.*Error" contracts/teachlink/src/errors.rsExpected Result: The following error enums should exist:
-
BridgeError(codes 100-147) -
EscrowError(codes 200-227) -
RewardsError(codes 300-309) -
MobilePlatformError(codes 400-407) -
AccessControlError(codes 500-505) -
AnalyticsError(codes 510-514) -
ReputationError(codes 520-525) -
TokenizationError(codes 530-536) -
AdvancedReputationError(codes 540-544)
grep "pub type.*Result<T>" contracts/teachlink/src/errors.rsExpected Result: All Result type aliases defined:
-
BridgeResult<T> -
EscrowResult<T> -
RewardsResult<T> -
AccessControlResult<T> -
AnalyticsResult<T> -
ReputationResult<T> -
TokenizationResult<T> -
AdvancedReputationResult<T>
awk '/^#\[contracterror\]/,/^}/' contracts/teachlink/src/errors.rs | \
grep -E "= [0-9]+" | sort -t'=' -k2 -nExpected Result: Error codes are:
- Unique (no duplicates)
- In correct ranges (no overlaps)
- Each error has meaningful variant name
# Check analytics.rs for error handling
grep -n "get_top_chains_by_volume" contracts/teachlink/src/analytics.rsExpected Result:
- Line ~340:
pub fn get_top_chains_by_volume_bounded(...) -> AnalyticsResult<Vec<...>> - Line ~385:
pub fn get_top_chains_by_volume(...) -> AnalyticsResult<Vec<...>> - Both functions return
Resulttypes - No
.unwrap()in sorting code
Specific Test:
# Verify no unwrap in sorting loops
sed -n '340,380p' contracts/teachlink/src/analytics.rs | grep "unwrap"Expected: No unwrap found
grep -n "check_role" contracts/teachlink/src/access_control.rsExpected Result:
- Line ~36:
pub fn check_role(...) -> AccessControlResult<()> - Returns
Resultinstead ofvoid - Error returned:
Err(AccessControlError::MissingRole) - No
panic!()call
Verification:
sed -n '36,42p' contracts/teachlink/src/access_control.rs | grep -c "panic"Expected: 0 panics found
# Check all three functions return Result
grep -E "pub fn (update_participation|update_course_progress|rate_contribution)" \
contracts/teachlink/src/reputation.rsExpected Result: All three functions signature should show:
-> ReputationResult<()>
Verify no assert!:
grep -c "assert!" contracts/teachlink/src/reputation.rsExpected: Should be 0 or only in test code
# Check getter functions
grep -A2 "pub fn get_token\|pub fn get_admin" contracts/teachlink/src/bridge.rsExpected Result:
- Both return
Result<Address, BridgeError> - No
.unwrap()calls - Proper error conversion:
.map_err(|_| BridgeError::StorageError)
cargo test --lib -p teachlink-contractExpected Result:
- All tests pass
- No test panics
- Error handling tests compile
cargo test --test error_handling_integration -p teachlink-contractExpected Result:
- Test file compiles without errors
- All integration tests pass
- Compilation successful (dummy test passes)
cargo test --lib -- --nocapture 2>&1 | grep -i "error\|result"Expected Result:
- Error handling is properly tested
- No unexpected panics in test output
- Result types are properly used in tests
File: contracts/teachlink/src/analytics.rs
Checklist:
- Imports include:
use crate::errors::{AnalyticsError, AnalyticsResult, ...} -
get_top_chains_by_volume_boundedreturnsAnalyticsResult<Vec<(u32, i128)>> -
get_top_chains_by_volumereturnsAnalyticsResult<Vec<(u32, i128)>> - Sorting code uses
.ok_or(AnalyticsError::InvalidIndex)?instead of.unwrap() - All Vec access properly handles errors
File: contracts/teachlink/src/access_control.rs
Checklist:
- Imports include:
use crate::errors::{AccessControlError, AccessControlResult, ...} -
check_rolefunction returnsAccessControlResult<()> - No
panic!()macro in check_role -
grant_roleandrevoke_roleconvert errors:.map_err(|_| BridgeError::Unauthorized)? - All authorization checks return Results
File: contracts/teachlink/src/reputation.rs
Checklist:
- Imports include:
use crate::errors::{ReputationError, ReputationResult} -
update_participationreturnsReputationResult<()> -
update_course_progressreturnsReputationResult<()> -
rate_contributionreturnsReputationResult<()> - Invalid rating check:
if rating > 5 { return Err(ReputationError::InvalidRating) } - No
assert!()macro in production code
File: contracts/teachlink/src/bridge.rs
Checklist:
-
get_tokenreturnsResult<Address, BridgeError> -
get_adminreturnsResult<Address, BridgeError> - No
.unwrap()on config getters - Fee recipient error handling:
.map_err(|_| BridgeError::StorageError)? - All repository operations properly handle errors
File: contracts/teachlink/src/errors.rs
Checklist:
-
AccessControlErrorenum defined with codes 500-505 -
AnalyticsErrorenum defined with codes 510-514 -
ReputationErrorenum defined with codes 520-525 -
TokenizationErrorenum defined with codes 530-536 -
AdvancedReputationErrorenum defined with codes 540-544 - All Result type aliases defined
- Error codes don't overlap
- All errors are contracterror decorated
ls -la contracts/teachlink/ERROR_HANDLING_GUIDE.mdExpected Result: File exists with:
- Overview section
- Principles section
- Error hierarchy defined
- Implementation patterns documented
- Checklist for implementation
- Testing guidelines
ls -la contracts/teachlink/tests/error_handling_integration.rsExpected Result: File exists with:
- Test module defined
- Test cases for each refactored module
- Manual testing checklist
- Compilation test
# Check WASM size (should not significantly increase)
ls -lh target/wasm32-unknown-unknown/release/teachlink_contract.wasmExpected Result: WASM size is reasonable and not significantly increased
# If available, run gas benchmark
./scripts/check_performance.shExpected Result: No significant gas cost increase from error handling
| Item | Status | Evidence |
|---|---|---|
| Build succeeds without errors | [ ] | cargo build --release output |
| No unwrap() in production code | [ ] | grep results |
| No panic!/assert! in production code | [ ] | grep results |
| All error enums defined | [ ] | errors.rs review |
| All Result types defined | [ ] | errors.rs review |
| Analytics functions return Result | [ ] | function signatures |
| Access Control functions return Result | [ ] | function signatures |
| Reputation functions return Result | [ ] | function signatures |
| Bridge functions return Result | [ ] | function signatures |
| Tests compile and pass | [ ] | cargo test output |
| Error codes are unique | [ ] | manual review |
| Documentation updated | [ ] | files exist |
| No silent failures | [ ] | code review |
Solution: Ensure all Result types are properly imported:
use crate::errors::{ErrorType, ErrorTypeResult};Solution: Update test code to handle Result types:
// Before
let result = function();
// After
let result = function()?; // or
match function() {
Ok(v) => { /* use v */ },
Err(e) => { /* handle e */ },
}Solution: Either use the Result or explicitly ignore it:
// Discouraged
function()?; // unused result
// Encouraged
let _ = function()?; // explicitly ignored
function()?; // used via ? operator in function returning ResultThe assignment is successfully completed when:
- ✓ All builds pass -
cargo build --releasecompletes without errors - ✓ No panics - Production code contains no panic!/assert! macros
- ✓ No silent failures - All fallible operations return Result types
- ✓ Specific errors - Each error type has its own variant with meaningful code
- ✓ Proper propagation - ? operator used for error propagation
- ✓ Tests pass - All unit and integration tests pass
- ✓ Documentation complete - Error handling guide and tests provided
- Run full test suite:
./scripts/test.sh - Check linting:
./scripts/lint.sh - Deploy to testnet:
./scripts/deploy-testnet.sh - Verify on-chain behavior matches expected error handling
Refer to:
- ERROR_HANDLING_GUIDE.md - Implementation patterns
- tests/error_handling_integration.rs - Test cases
- src/errors.rs - Error definitions