One retry policy for two very different failures
“No connection” on one tab while the status bar carried on updating, from a
server that answered every request in that window with a 200. Reported
twice before I understood it.
Two very different failures were sharing one retry policy. Three attempts, 400ms and 800ms apart — 1.2 seconds all told.
That is exactly right for a phone with no signal. It is useless for a server that is momentarily gone: a Cloud Run revision switch takes several seconds, so all three attempts landed inside the same gap, and the player was shown a dead screen by a service that was completely fine a moment later.
So the policy is split by which kind of failure it is.
A name that will not resolve, and a network that is not there, are answers — not accidents. Waiting cannot change either of them, so those still fail in 1.2 seconds and the player gets told quickly.
Everything else is treated as the server briefly not being there, and is waited out.
The general form is worth having: retry is not one decision. It is a question about what the failure means. A failure that is a settled fact should fail fast, because retrying is just making the user wait to be told something you already knew. A failure that is a moment in time should be waited out, because the answer is about to change.
Using one timing for both guarantees you get one of them wrong. We had it wrong in the direction that makes a working service look broken.