Skip to main content
Sigil provides robust error handling through Rust’s Result type combined with automatic storage rollback. Understanding when to use errors versus panics, and how rollback works across contract calls, is essential for writing correct contracts.

The Error Type

Defined in core/indexer/src/runtime/wit/deps/built-in.wit.

When to Use Result vs Panic

Use Result for Expected Errors

Expected failure cases:
Use cases:
  • Business logic errors (insufficient funds, unauthorized access)
  • Invalid input validation
  • Cross-contract call errors
  • Any error the user might trigger through normal operation

Use panic! for:

Invariant violations:
Use cases:
  • Invariant violations (should never happen)
  • Internal bugs
  • Unrecoverable errors
Important: Panics roll back ALL storage changes across the entire call chain.

Creating Custom Error Messages

Basic Error Messages

Reusable Error Constructors

Overflow and Division Errors

Checked Operations

Integer and Decimal types provide checked operations:
Usage:

Unchecked Operations

Standard operators panic on overflow:
When to use unchecked:
  • When you’ve already validated the operation won’t overflow
  • When panic is acceptable (simple contracts, testing)
  • When performance is critical (avoid double checks)
When to use checked:
  • User-provided inputs
  • Complex calculations
  • When you want to return a specific error message

Rollback Semantics

What Rolls Back

When a function returns an Err or panics, ALL storage modifications are rolled back. Example:

Cross-Contract Rollback

Both errors and panics roll back the entire call chain:
This applies across cross-contract calls:
  • If Contract A calls Contract B, and B returns an error
  • ALL storage changes in both A and B are rolled back
  • The entire transaction has no effect

No Partial Commits

A transaction either:
  • Completes fully with all storage changes persisted
  • Fails entirely with no storage changes
This applies across all cross-contract calls in the transaction.

Error Handling Best Practices

1. Validate Early

2. Use Descriptive Error Messages

3. Propagate Cross-Contract Errors

4. Handle Option Types Carefully

5. Follow Checks-Effects-Interactions (CEI) Pattern

Why this matters:
  • External calls can fail
  • State changes before the call are preserved (unless you propagate the error)
  • CEI pattern makes reasoning easier

Testing Errors

Testing Expected Errors

Testing Error Messages