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

Handling Partial Failures in Iterators

Process sequences where specific items might fail while preserving the valid rest.

In this lesson, you will learn how to process sequences of data while gracefully filtering out individual errors without stopping the entire iteration process.

The "All or Nothing" Problem

When you use map on an iterator and return a Result, you might be tempted to use the question mark operator (?) inside a closure. However, ? requires the entire function to return a Result. If you are inside an iterator chain, using ? will cause the first error it encounters to short-circuit the whole operation, abandoning any remaining items in your collection.

The partition Approach

If you want to keep the valid items and the errors separate, you can use the partition method. This splits your iterator into two distinct collections: one for successes and one for failures.

let inputs = vec!["1", "2", "banana", "4"];

let (successes, errors): (Vec<_>, Vec<_>) = inputs
    .into_iter()
    .map(|s| s.parse::<i32>())
    .partition(Result::is_ok);

// successes is now [Ok(1), Ok(2), Ok(4)]
// errors is now [Err(ParseIntError)]

Filtering and Unwrapping

Alternatively, if you only care about the valid results and want to discard errors, you can use filter_map. By passing the Result into ok(), the Result is converted into an Option. Ok values become Some(value), and Err values become None. Since filter_map automatically discards None values, your final iterator contains only the successful results.

let inputs = vec!["1", "2", "banana", "4"];

let valid_numbers: Vec<i32> = inputs
    .into_iter()
    .filter_map(|s| s.parse::<i32>().ok())
    .collect();

// valid_numbers is [1, 2, 4]

This pattern allows you to remain "fault-tolerant." Instead of crashing or stopping your program because of one malformed input, you safely harvest the data that works and move on. You can choose to log the errors separately or simply ignore them, depending on your application's needs.

Key Takeaway: Use filter_map(Result::ok) to gracefully discard errors or partition() to categorize results, avoiding the short-circuiting behavior of the question mark operator.