Convention for unwrapping that can't fail


#1

Hi,

I’m writing a small command line tool at the moment, and I find myself using unwrap in a couple of places:

  1. On Option values that are guaranteed to contain somethings (they’ve already been validated by clap)
  2. On return values from functions that will almost certainly not fail (e.g. will only fail if current_year >= 262143)

What’s the conventional way of handling these cases? It seems a waste to try and elegantly handle and report these errors that will never happen. Does it make sense to use unwrap here instead?


#2

Best shot imho: Use expect with an easily greppable message, like “Verified by clap” or “Post-apocalypse use not supported”. That has your back if you misjudge (I sure did that in the past), but still does not make you jump through unneeded loops.


#3

Same here. I see use of expect() as a way to state in code: “This is not a lazy debugging unwrap() that was forgotten around, I consciously decided to panic if this condition is false, and here’s why”. Kind of like asserts.

Of course, whenever possible, the relevant interfaces and data structures should ultimately be redesigned so that you don’t have Options that are guaranteed to be Some or the like. That’s just confusing design and a waste of run-time CPU cycles.


#4

good question i would use unwrap_or_else(|| unreachable!()) i think


#5

I hadn’t thought of this, but I really like it. If the unwrap failing is actually unreachable, I think I’ll go for this.

I suppose expect is better in cases where it technically could fail (262143AD problem, for example).


#6

I’m not sure why any of these are better than unwrap with a comment next to / above it.


#7

@quadrupleslap I guess comments are easy to lose track of and go out of date, but that’s down to preference.

@HadrienG I actually went the latter route in the end: I swapped clap for structopt which got rid of 90% of the unwraps, and then made a few structs with invariants which took care of the last few.

Though I still like unwrap_or_else(|| unreachable!()) in principle.


#8

I find expect better than unwrap with a comment because I can then treat unwrap as a TODO, by the time of release all unwraps should be gone and replaced with either proper error handling or expect calls with some minimal rationale.


#9

This is what I do as well. Since Rust’s error handling conventions, while sound, are a bit unpleasant to work with in practice, I tend to write many unwraps when experimenting around. In the cleanup and consolidation phase, grepping for unwrap in the code and treating every occurrence as a TODO is then quite convenient.