Proposal: `ok_or_else()` function on `std::result::Result`

I often have to convert a std::result::Result into an std::option::Option (very useful when chaining different Option and Result types using and_then()). This is easy with the ok() function. The problem is that you lose the Err(_), which is expected though, since Option only has None. But what if I still want to do something with the error message, for example log it?

We could do this using this code:

result.map_err(|err| {
   log::error!("{err}") 
   err
}).ok();

but what if we had an api like this:

result.ok_or_else(|err| log::error!("{err}"));
3 Likes

The issue I see with the name Result::ok_or_else specifically is Option::ok_or_else(). The 2 methods have quite different behavior, so giving them the same name doesn't sound great to me.

Hmm tbh, I don't think they are too far apart. On Option::ok_or_else() there is this comment:

Transforms the Option<T> into a Result<T, E>, mapping Some(v) to Ok(v) and None to Err(err()).

The proposed Result::ok_or_else() would read instead: Transform the Result<T, E> into a Option<T>, mapping Ok(v) to Some(v) and calling err() using E.

I actually think this would be the best counterpart to the Option::ok_or_else() as we can't store any value in None.

My personal feeling is that Result and Option already have so many (proposed) methods that discoverability suffers. A new method would need to make useful patterns much more readable and/or shorter.

result.ok_or_else(|err| log::error!("{err}"));
result.map_err(|err| log::error!("{err}")).ok();

The map_err variant already looks clear to me and is just two characters longer. I think the name of your proposed method should make clear that the error is consumed. Something like drop_err_with as a counter part to the nightly inspect_err. Not sure if drop is the correct verb though.

3 Likes

For this style or logging I like to use tap's tap_err method, which often looks like this:

result 
    .tap_err(|e| log::error!("{e}"))
    .unwrap_or_default();
1 Like

This is already implemented with the nightly method inspect_err

Tracking issue for inspect_err if anyone's curious

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.