# Option vs. Result advice

**URL:** <https://users.rust-lang.org/t/option-vs-result-advice/53972>\
**Category:** uncategorized\
**Created:** [January 10, 2021, 10:04pm UTC](https://users.rust-lang.org/t/option-vs-result-advice/53972 "2021-01-10T22:04:43Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![alanhkarp](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/alanhkarp/32/4011_2.png) [@alanhkarp](https://users.rust-lang.org/u/alanhkarp)\
**Post date:** [January 10, 2021, 10:04pm UTC](https://users.rust-lang.org/t/option-vs-result-advice/53972/1 "2021-01-10T22:04:44Z")

</div>

I have been returning `Ok<Option<foo>>` when something might not be there, such as a failed lookup, and `Err<error>` when there's been an error of some kind. However, I just looked at channel's try\_recv() and see that it returns Err if there is nothing to read or if the channel is closed. Is that the pattern I should be using?

Getting Err is inconvenient in my case, because I want to supply a default value if the channel is empty and use ? to return if there's an error.

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/scottmcm/32/4286_2.png) [@scottmcm](https://users.rust-lang.org/u/scottmcm)\
**Post date:** [January 10, 2021, 10:31pm UTC](https://users.rust-lang.org/t/option-vs-result-advice/53972/2 "2021-01-10T22:31:41Z")

</div>

If `Result<Option<Foo>, Error>` best represents how you think about the behaviour, then you should absolutely use it.

---

<div class="post-metadata">

**Author:** ![jsgf](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/jsgf/32/144_2.png) [@jsgf](https://users.rust-lang.org/u/jsgf)\
**Post date:** [January 10, 2021, 10:39pm UTC](https://users.rust-lang.org/t/option-vs-result-advice/53972/3 "2021-01-10T22:39:15Z")

</div>

It depends. For things like a key-value store, I'm a big advocate of returning `Result<Option<T>, E>` where `Ok(Some(value))` means "here's the thing you asked for", `Ok(None)` means "the thing you asked for definitely doesn't exist", and `Err(...)` means "I can't say whether the thing you asked for exists or not because something went wrong".

I think APIs which require the callers to look at errors to make decisions about what to do next should be avoided; the common case for errors should just be "return to caller (maybe with some extra context)". The exception is the rare cases like where you have some retry logic of some form (but that introduces its own problems).

If failure isn't possible (eg, in memory local store), then just return `Option<T>`. Or if the semantics of the system are such that it is an error to ask for things that don't definitely exist, then use `Result<T, E>` (or map `None` to an error everywhere).

---

<div class="post-metadata">

**Author:** ![alice](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/alice/32/9777_2.png) [@alice](https://users.rust-lang.org/u/alice)\
**Post date:** [January 10, 2021, 10:52pm UTC](https://users.rust-lang.org/t/option-vs-result-advice/53972/4 "2021-01-10T22:52:19Z")

</div>

Returning `Result<Option<T>, E>` is perfectly fine. The thing you're seeing on channels is mostly something people do on channels and that's it.

---

<div class="post-metadata">

**Author:** ![alanhkarp](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/alanhkarp/32/4011_2.png) [@alanhkarp](https://users.rust-lang.org/u/alanhkarp)\
**Post date:** [January 11, 2021, 1:37am UTC](https://users.rust-lang.org/t/option-vs-result-advice/53972/5 "2021-01-11T01:37:01Z")

</div>

Is there a reason it's done on channels? I tried to think of one but couldn't.

---

<div class="post-metadata">

**Author:** ![alice](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/alice/32/9777_2.png) [@alice](https://users.rust-lang.org/u/alice)\
**Post date:** [January 11, 2021, 7:46am UTC](https://users.rust-lang.org/t/option-vs-result-advice/53972/6 "2021-01-11T07:46:12Z")

</div>

Either way is fine, and this is what the people who wrote it came up with.

---

<div class="post-metadata">

**Author:** ![vorner](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/vorner/32/6006_2.png) [@vorner](https://users.rust-lang.org/u/vorner)\
**Post date:** [January 11, 2021, 8:07am UTC](https://users.rust-lang.org/t/option-vs-result-advice/53972/7 "2021-01-11T08:07:42Z")

</div>

I think it depends on your mental model. You have a [`try_lock`](https://doc.rust-lang.org/std/sync/struct.Mutex.html) on mutex and when you're using it, you're probably thinking that the mutex generally should be free, but one never knows and it's somehow possible to deal with the exceptional situation of not being.

Channels, as another synchronization primitive, might come into that category.

But of course in both cases you can have the mental model of just wanting to have a look if it might be accidentally free right now... in which case the API doesn't exactly match that model.

The nested options/results are often better and you even have methods that help working with them, like [`transpose`](https://doc.rust-lang.org/std/option/enum.Option.html#method.transpose).

---

<div class="post-metadata">

**Author:** ![petar-dambovaliev](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/petar-dambovaliev/32/18929_2.png) [@petar-dambovaliev](https://users.rust-lang.org/u/petar-dambovaliev)\
**Post date:** [January 11, 2021, 4:03pm UTC](https://users.rust-lang.org/t/option-vs-result-advice/53972/8 "2021-01-11T16:03:06Z")

</div>

I think `Result<Option<T>, E>` tells you the whole story by definition, which is why i like it more.  
`Result<T, E>` does not tell me that one of the errors might be the fact that there is no `T`, unless i go read the definition of `E`.

---

<div class="post-metadata">

**Author:** ![alice](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/alice/32/9777_2.png) [@alice](https://users.rust-lang.org/u/alice)\
**Post date:** [January 11, 2021, 4:05pm UTC](https://users.rust-lang.org/t/option-vs-result-advice/53972/9 "2021-01-11T16:05:19Z")

</div>

It's worth noting that there are some channels that return `Option<T>` for `recv`, e.g. [this one](https://docs.rs/tokio/1.0.1/tokio/sync/mpsc/struct.Receiver.html#method.recv).

---

<div class="post-metadata">

**Author:** ![system](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/system/32/51372_2.png) [@system](https://users.rust-lang.org/u/system)\
**Post date:** [April 11, 2021, 4:05pm UTC](https://users.rust-lang.org/t/option-vs-result-advice/53972/10 "2021-04-11T16:05:24Z")

</div>

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.
