Skip to content

feat(flashblocks): Replace eyre::Result with Domain-Specific Error Types #312

@refcell

Description

@refcell

Summary

Introduce StateProcessorError enum to replace generic eyre::Result throughout the flashblocks crate.

Problem

Current error handling uses eyre::Result everywhere, which:

  • Loses semantic information (was it validation? execution? storage?)
  • Makes error matching in tests difficult and fickle
  • Provides no structured context for debugging
  • Can't distinguish recoverable vs unrecoverable errors

Example of current ambiguous errors:

Err(eyre!("missing headers"))
Err(eyre!("no flashblocks"))
Err(eyre!("first flashblock missing base"))

Solution

New file: src/error.rs

#[derive(Debug, thiserror::Error)]
pub enum StateProcessorError {
    // Protocol errors (upstream issues)
    #[error("invalid flashblock sequence: expected {expected}, got {got}")]
    InvalidSequence { expected: u64, got: u64 },

    #[error("flashblock missing base payload")]
    MissingBase,

    #[error("cannot assemble block from empty flashblocks")]
    EmptyFlashblocks,

    // Operational errors (sync issues)
    #[error("missing canonical header for block {block_number}")]
    MissingCanonicalHeader { block_number: u64 },

    #[error("state provider error: {0}")]
    StateProvider(String),

    // Execution errors
    #[error("transaction execution failed: {tx_hash}")]
    TransactionExecution { tx_hash: B256 },

    #[error("sender recovery failed: {0}")]
    SenderRecovery(String),

    // Build errors
    #[error("missing headers in pending blocks")]
    MissingHeaders,

    #[error("missing flashblocks in pending blocks")]
    MissingFlashblocks,
}

Benefits

// Before: opaque error
Err(eyre!("first flashblock missing base"))

// After: matchable, structured
Err(StateProcessorError::MissingBase)

// Enables test assertions
assert!(matches!(result, Err(StateProcessorError::MissingBase)));

// Enables targeted error handling
match error {
    StateProcessorError::MissingCanonicalHeader { .. } => /* retry sync */,
    StateProcessorError::InvalidSequence { .. } => /* wait for recovery */,
    _ => /* log and continue */,
}

Acceptance

  • All eyre!() calls replaced with specific variants
  • Error types exported from lib.rs
  • Unit tests can match on specific errors
  • Integration tests still pass

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions