/** * Run a server action, retrying it ONCE if the call rejects at the * transport layer. * * iOS Safari (and Safari generally) frequently drops the first POST sent * on a keep-alive socket that the server closed while the connection sat * idle — e.g. while the user typed their credentials. The request fails * instantly with `NSURLErrorNetworkConnectionLost` ("The network * connection was lost", -1005); a retry lands on a fresh connection and * succeeds. This is why a first login/signup tap shows "An unexpected * error occurred" and the second tap works. * * Only a *thrown* rejection is retried. A server action that returns a * value — including an application-level `{ error }` ("Invalid email or * password", a rate-limit message) — is a real result and passes * straight through untouched. A lost-on-a-stale-socket POST never * reached the server, so retrying it once is safe. */ export async function retryOnTransportError(fn: () => Promise): Promise { try { return await fn(); } catch { return await fn(); } }