312. Duration::saturating_sub — Your Timeout Budget Ran Out, and the Subtraction Panicked
Duration - Duration panics on underflow — and budget - elapsed underflows the moment a slow operation blows the budget.
A classic timeout-budget loop: give the whole request 200 ms, subtract what each step used, hand the rest to the next step. The subtraction is the trap:
| |
Duration is unsigned — there is no negative duration — so the moment elapsed exceeds budget, Sub has nothing valid to return and panics. It works fine in tests where every step is fast, then crashes in production the first time a step stalls.
The fallible and saturating versions
checked_sub returns an Option, which makes “budget exhausted” an explicit case instead of a crash:
| |
If “no time left” should just mean zero — say, the value goes straight into recv_timeout from bite 283 — saturating_sub clamps instead:
| |
The same family exists for the other direction: checked_add / saturating_add for accumulating durations, and checked_mul / checked_div for scaling them.
This is the integer twin of this morning’s bite 311: there, float math produced a negative that panicked at the Duration conversion; here, Duration math itself hits the floor. Either way, the fix is the same — reach for the method that returns a value you can handle instead of the operator that panics.