Skip to content

ADR-0002: Error Handling Strategy

Status

Accepted

Context

Accounting software needs robust error handling. Errors can occur during:

  • Parsing (syntax errors, invalid dates, malformed amounts)
  • Loading (file not found, include cycles, path traversal)
  • Validation (unbalanced transactions, unknown accounts)
  • Query execution (type mismatches, unknown columns)

We need to decide:

  1. How to represent errors (enums, traits, strings)
  2. Whether to fail-fast or collect multiple errors
  3. How to provide good error messages with source locations

Decision

Error Representation

Use thiserror to derive Error implementations with strongly-typed error enums per crate:

  • ParseError in rustledger-parser
  • LoadError in rustledger-loader
  • ValidationError in rustledger-validate
  • QueryError in rustledger-query

Each error type includes relevant context (spans, file paths, expected vs found values).

Error Collection vs Fail-Fast

Parser: Collect errors and continue parsing to report multiple issues at once. Return ParseResult with both directives and errors vectors.

Loader: Collect errors for parse failures and path issues, but fail-fast on include cycles (which would cause infinite loops).

Validator: Collect all validation errors to report everything wrong with a ledger in one pass.

Query: Fail-fast on query errors since partial results would be misleading.

Source Locations

All errors that can occur at specific source locations include Span information (byte offsets). The SourceMap tracks file contents for error rendering.

Consequences

Positive

  • Users see all syntax errors at once, not one at a time
  • Typed errors enable programmatic handling
  • Span information enables IDE-quality error messages
  • #[must_use] on Result types prevents ignored errors

Negative

  • Error collection requires more complex parser recovery logic
  • Multiple error types mean more code to write
  • Must be careful to propagate errors correctly

Neutral

  • Using thiserror rather than manual impl Error