Skip to content

hardening(subscription_renewal): replace panic!/unwrap/expect with typed Result errors - #2

Open
wendypetersondev wants to merge 1 commit into
mainfrom
hardening/subscription-renewal-typed-errors
Open

hardening(subscription_renewal): replace panic!/unwrap/expect with typed Result errors#2
wendypetersondev wants to merge 1 commit into
mainfrom
hardening/subscription-renewal-typed-errors

Conversation

@wendypetersondev

Copy link
Copy Markdown
Owner

Summary

Closes Calebux#1053

Replaces all ~20 bare panic!/.expect()/.unwrap() calls on user-reachable paths in subscription_renewal/src/lib.rs with a #[contracterror] enum, so clients receive predictable, inspectable error codes instead of opaque contract panics.

Changes

lib.rs

  • Added ContractError enum with 19 variants (discriminants 1–19, required by Soroban ABI):
    AlreadyInitialized, NotInitialized, ProtocolPaused, RenewalLockActive, NoRenewalLock, SubscriptionNotFound, AlreadyCancelled, LifecycleNotFound, SubscriptionFailed, RenewalLockRequired, RenewalLockExpired, DuplicateCycle, CooldownActive, InvalidApproval, OutsideRenewalWindow, IntegrityViolation, SpendingCapExceeded, GlobalCapExceeded, InvalidWindow
  • Every public function now returns Result<T, ContractError>
  • Renamed IntegrityViolation and RenewalLockExpired event structs to IntegrityViolationEvent / RenewalLockExpiredEvent to avoid name collision with error enum variants
  • Zero panic!/.expect()/.unwrap() remain on any user-reachable path

test.rs

  • Replaced all #[should_panic(expected = "...")] tests with try_* client method calls and assert_eq!(err, ContractError::Variant) assertions
  • All happy-path calls updated with .unwrap()

fuzz.rs

  • Removed catch_unwind / AssertUnwindSafe — fuzz harnesses now use try_* and assert typed error codes

Acceptance criteria

  • No bare panics on user-reachable paths
  • Typed ContractError enum exposed in contract ABI
  • Tests assert specific error codes, not panic strings
  • Logic and invariants unchanged (spending caps, cycle guard, lock TTL, etc.)

…ped Result errors

Closes Calebux#1053

- Add ContractError #[contracterror] enum (19 variants, discriminants 1-19)
- Convert init, set_paused, set_logging_contract, acquire_renewal_lock,
  release_renewal_lock, cancel_sub, approve_renewal, renew, get_sub,
  get_lifecycle, set_window, set_user_cap to return Result<T, ContractError>
- Replace every panic!/expect()/unwrap() on user-reachable paths with
  typed Err(ContractError::*) — zero bare panics remain
- Rename IntegrityViolation/RenewalLockExpired event structs to
  IntegrityViolationEvent/RenewalLockExpiredEvent to avoid clash with enum
- Update all #[should_panic] tests to use try_* client methods and
  assert_eq!(err, ContractError::Variant) patterns
- Update fuzz tests: remove catch_unwind, assert typed error codes instead
- No logic changes; all invariants and spending caps preserved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Hardening: replace panic!/unwrap/expect with typed Result errors in subscription_renewal

1 participant