Rust - Handling Results In A Map Closure

Lobsters Hottest Tools

Summary

This article addresses the common Rust error when using a function that returns a Result within a map closure, and provides multiple solutions: collecting results, using a loop, filter_map, and try_fold.

<p><a href="https://lobste.rs/s/1r09vz/rust_handling_results_map_closure">Comments</a></p>
Original Article
View Cached Full Text

Cached at: 07/04/26, 06:38 AM

# Handling Results In A Map Closure Source: [https://reemus.dev/tldr/rust-handling-results-in-map-closure](https://reemus.dev/tldr/rust-handling-results-in-map-closure) Are you encountering an error when trying to use a function that returns a`Result`within a`\.map\(\)`closure in Rust? I'm sure this is a common problem people face when learning to use Rust\. Thankfully, the solution is actually quite simple\. ## Problem Consider the following Rust code where we have two functions, both returning Result types\. The first function prefixes a line \(a string slice\), and the second function takes a list of lines and prefixes each using the first function\. ``` use std::error::Error; fn prefix_line(line: &str) -> Result<String, Box<dyn Error>> { Ok(format!("PREFIX: {}", line)) } fn prefix_each(lines: &[&str]) -> Result<Vec<String>, Box<dyn Error>> { let result = lines .iter() .map(|line| prefix_line(line)?) .collect::<Vec<_>>(); Ok(result) } ``` ![rust-icon](https://reemus.dev/ui/icons/devicons/rust-white.svg) Attempting to compile this code results in an error on line 10: > the '?' operator can only be used in a closure that returns 'Result' or 'Option' \(or another type that implements 'FromResidual'\) \[E0277\] Help: the trait 'FromResidual<Result<Infallible, Box<dyn StdError\>\>\>' is not implemented for 'std::string::String' Breaking down the error: - The`map`function takes a closure as it's argument - The`?`operator inside the`\.map\(\)`closure is problematic - This is because the`?`operator expects the closure to return a`Result`or`Option` - Instead, the closure's return type is inferred to match the expected output type of map, which is`String` - Since`String`doesn't implement`FromResidual`, you get the error ## Solutions ### Collect the results The simplest way I've found to solve this issue: - Call`prefix\_line\(line\)`without the`?`operator which outputs`Vec<Result<\.\.\.\>\>` - Use`collect::<Result<Vec<\_\>, \_\>\>\(\)?`to correctly infer types, collect the`Results`and propagate errors if any - Leaving us with our desired output`Vec<String\>` ``` fn prefix_each(lines: &[&str]) -> Result<Vec<String>, Box<dyn Error>> { let result = lines .iter() .map(|line| prefix_line(line)) .collect::<Result<Vec<_>, _>>()?; Ok(result) } ``` ![rust-icon](https://reemus.dev/ui/icons/devicons/rust-white.svg) ### Using a loop The obvious initial solution but it has drawbacks such as: - It breaks the functional style - It requires a mutable variable ``` fn prefix_each(lines: &[&str]) -> Result<Vec<String>, Box<dyn Error>> { let mut result = Vec::new(); for line in lines { result.push(prefix_line(line)?); } Ok(result) } ``` ![rust-icon](https://reemus.dev/ui/icons/devicons/rust-white.svg) ### Using filter\_map - `filter\_map`discards`Err`values collecting only successful`Ok`values - Useful if you want to ignore errors and only care about the successful results ``` fn prefix_each(lines: &[&str]) -> Result<Vec<String>, Box<dyn Error>> { let result = lines .iter() .filter_map(|line| prefix_line(line).ok()) .collect::<Vec<_>>(); Ok(result) } ``` ![rust-icon](https://reemus.dev/ui/icons/devicons/rust-white.svg) ### Using try\_fold - Use`try\_fold`to aggregate results and handle errors gracefully - It allows you to return a Result type directly ``` fn prefix_each(lines: &[&str]) -> Result<String, Box<dyn Error>> { let result = lines.iter().try_fold(String::new(), |mut acc, line| { prefix_line(line).map(|prefixed_line| { acc.push_str(&prefixed_line); acc.push_str("\n"); acc }) })?; Ok(result) } ``` ![rust-icon](https://reemus.dev/ui/icons/devicons/rust-white.svg)

Similar Articles

A Novel Look at Error Handling in Rust

Lobsters Hottest

The article discusses different error handling patterns in Rust, including panicking, using Option, Result, and default recovery, and proposes a novel approach to error handling beyond simple propagation or recovery.

Custom Errors Are Non-Negotiable in My Rust Applications

Lobsters Hottest

A blog post advocating for custom error types in Rust applications, explaining how to create a unified AppError enum using map_err and From traits to streamline error handling across different subsystems.

Work In Progress Rust

Lobsters Hottest

This article presents techniques and a library for deferring error handling in Rust during development, allowing developers to temporarily downgrade errors to warnings to maintain productivity without sacrificing correctness.

A data race that doesn't compile

Hacker News Top

The article explains how the author taught Rust's type system to reject parallel reducer pipelines that could cause data races, using a type-level disjointness technique in the ruxe library.

iddqd, or the hardest kind of unsafe Rust

Lobsters Hottest

This article introduces iddqd, a Rust library that provides maps where keys are borrowed from values, reducing duplication and synchronization issues. It discusses the challenges of writing unsafe Rust code and how the library maintains correctness.