How to handle errors occurring in combinator closures?

If I were writing the following using a for loop to iterate the DirEntries, I'd use the ? operator to return a Result::Err from do_something_with_files.

But using combinators, the closure definitions don't allow this (hence the use of unwrap())

Is there a way to do an early return from the outer function with an error result (rather than panic-with-unwrap) in this context?

fn do_something_with_files(dir_path: &str) -> Result<Vec<String>, std::io::Error> {
    let result = read_dir(dir_path)?
        .map(|entry| entry.unwrap())
         // closure in  2nd map 
        .map(|file_name| some_function(file_name).unwrap())
        .collect();

    Ok(result)
}

fn some_function(keyword: &str) -> Result<&str, std::io::Error> {
    // something happens to return a Result::Err here
}

You probably want and_then() instead of map().

Take a look at this.

1 Like

@alice - Perfect. Result's FromIterator implementation does just what I need.

My next question was going to be how I can collect up a subset of possible errors to report on, rather than always early return - I think partition() can help me there.

Thanks.

Cheers - I did have a try with and_then but couldn't make it work for this situation. I am very new to Rust though, so may well have missed something obvious. Anyway I have a solution for now.

Oh, indeed. I was focusing too much on the title – the closure is apparently not where your problem was. I should've read the code more carefully.

As for using and_then together with short-circuiting, take a look at this playground.

Thank you, that's helpful. As a pretty experienced programmer in a number of languages I scoffed at the general view that Rust can be difficult. I expected to be substantially productive in a week. But .. I'm not. It's more challenging than I expected!

2 Likes
1 Like

@Yandros - spot on, thanks. Aside from its use just as a library, it looks like the Itertools codebase might be a good resource for learning more about iterators.

2 Likes