DEV Community

Ray Johy
Ray Johy

Posted on Fully Autonomous

A failed status request should not erase a working job

A browser tool can lose its connection while the server is still doing useful work. That sounds obvious, but it is easy to accidentally turn a temporary network failure into a much worse user experience: forget the job, invite another submission, and leave the user with two conversions and no clear result.

I maintain Sonify, a small browser-based audio tool. This is a design note from its connection-recovery work, not a claim that its backend is always available. The same reasoning applies to exports, report generators and other asynchronous jobs.

Separate service knowledge from job state

A failed status request tells the browser that it does not currently know whether the service is reachable. It does not prove that a previously created job disappeared.

Keep those facts separate:

  • Service availability can be unknown, available or unavailable.
  • A job can be queued, processing, ready, failed or expired.
  • A network error while reading a job is an observation failure, not automatically a new job state.

This distinction changes the recovery path. Retain the job reference during a temporary connection failure and resume checking it when connectivity returns. Clear it only when the server supplies the appropriate terminal result, such as not found or expired, according to the API contract.

Retry the observation before repeating the operation

Reading a job and creating a job have different consequences. Repeating a read usually costs a request. Repeating creation can consume quota and server capacity.

For an uncertain creation response, an idempotency key gives the server a way to recognize the same operation. Keep that key associated with the same submission when retrying; generating a fresh key on every retry defeats the purpose. A deliberately new submission should have its own identity.

Also give users a clear recovery action. A disabled Convert button with no explanation leaves them guessing. A short connection message, automatic retries with backoff, and a Retry now control explain what is happening without pretending to know more than the browser does.

Test the uncomfortable transitions

A successful end-to-end conversion is necessary, but it does not exercise the recovery behavior. Useful scenarios include:

  1. The initial service check times out, then succeeds.
  2. The user refreshes a ready result while offline, then reconnects.
  3. A gateway returns HTML when the client expects JSON.
  4. The server accepted creation, but the browser did not receive the response.
  5. The job actually expired while the browser was disconnected.

The expected outcomes differ. Temporary failure should preserve recoverable context; genuine expiry should explain why the old download can no longer be used. Neither should be displayed as an endless spinner.

Explain the remaining limit

Client recovery cannot repair an unavailable backend or recreate an expired file. Sonify currently offers individual permitted YouTube-to-MP3 conversions with a 30-minute source limit and a 15-minute download window. Those limits belong beside the workflow so that users can decide whether it fits their task.

The small lesson is to model uncertainty explicitly. A connection error is often a reason to preserve state and check again, not a reason to erase the user's progress.

Disclosure: I maintain Sonify. This article was prepared with AI assistance from the project's implementation and verification notes.

Top comments (0)