Course contentsShow
← Rust
Lesson 871 of 1,9107. Error Handling PatternsFree lesson

Strict vs Lax Error Propagation

Evaluate the design trade-offs between bubbling up errors versus local recovery.

In this lesson, you will learn how to weigh the architectural trade-offs between forcing immediate error bubbling (Strict) and attempting local recovery (Lax).

When designing functions, you face a fundamental choice: should your code propagate errors as soon as they occur using the ? operator, or should it attempt to resolve them internally?

The Strict Approach

Strict propagation treats any failure as a signal to cease execution immediately. By using ?, you ensure that your function never enters an inconsistent state. The logic is linear, readable, and predictable. However, the trade-off is "error inflation"—your call stack becomes filled with functions that have no idea how to fix a problem, but are forced to act as conduits for it.

fn process_user_data(input: &str) -> Result<Data, Error> {
    let raw = parse(input)?; // Strict: if it fails, we abort.
    let cleaned = sanitize(raw)?;
    Ok(cleaned)
}

The Lax Approach

Lax propagation (or local recovery) involves "swallowing" specific errors to provide fallback behavior. This is useful when an error is expected or non-fatal. By using unwrap_or, unwrap_or_else, or match statements to recover, you keep the caller oblivious to the internal hiccup.

fn get_config(key: &str) -> Config {
    // Lax: if the file is missing, provide a sensible default.
    load_file(key).unwrap_or_else(|_| Config::default())
}

Choosing Your Strategy

The trade-off boils down to responsibility.

  • Choose Strict when the error represents a violation of invariants or a condition the caller must handle to maintain system integrity. This creates "fail-fast" systems that are easier to debug because the error origin is usually the site of the failure.
  • Choose Lax when the error is a domain-specific nuance, like a missing cache entry or a non-critical preference file. Lax handling hides complexity from the caller, but it carries the risk of "silent failure," where the system continues running in a degraded or unintended state without the higher-level logic being aware.

Strict propagation ensures correctness; Lax propagation ensures resilience. Use Strict for critical data paths and Lax for graceful degradation of services.

Key Takeaway: Strict propagation maintains system integrity through fail-fast behavior, while Lax propagation provides resilience by resolving non-critical errors locally.