Telling a no from a not yet#
Week 7 — SLOP3092
← Back to the lecture pageLast week#
Two operators, one payout, and a runbook line standing in for a lock.
The failure had no code in it and behaved exactly like the ones that did.
This week: two errors, one retry loop#
Two failures that will never succeed however often they are repeated.
A malformed message a queue consumer cannot parse, and a 400 saying the request itself is wrong.
At the instant they fail, both look like the transient faults every earlier week retried successfully.
The reflex#
The retry wrapper does not read the failure.
An exception is an exception and a status code is an integer, so both go round again.
Retrying a 400 forever#
What that does#
The malformed message goes back onto the queue, blocks the messages behind it, and occupies the consumer for as long as anyone lets it.
The 400 draws down week 5’s shared budget and will never succeed.
Meanwhile a 429 in the same batch — the one response explicitly asking the client to slow down — gets retried immediately.
The fix#
Read the failure before deciding.
| Response | Retry? |
|---|---|
5xx, 429 | yes |
400, 403, 422 | no |
A 429’s Retry-After overrides whatever schedule the client had planned. A message that has failed a bounded number of times goes to a dead-letter queue rather than back onto the main one.
What the classification depends on#
Somebody else’s server using status codes correctly. A dependency that answers 400 for a transient fault now fails permanently on the first attempt.
And a dead-letter queue only fixes something if a person reads it. Unread, it is the same poison message with better filing.
Who decides#
library.
A consumer sees one message and a call site sees one response, so neither has the memory to notice it is looping.
The library is where the attempt count and the classification table both live long enough to be right, and the only place where correcting the table corrects every caller at once.
In the lab#
- Sort a log of mixed failures — malformed payloads,
400s,429s, timeouts — into retryable and not - Wire the classification into both a consumer and a client
- Confirm the poison message reaches the dead-letter queue
- Confirm the
429waits out itsRetry-After
Next week#
A single failure can now be classified.
Next: a dependency down for minutes, and every caller finding out separately.
← Back to the lecture page