Fix the retry policy behind an HTTP client wrapper
Your task
An assistant wrapped an HTTP client in a retry helper and tested it with one mocked case: a network error, then a 200. No test checked the outcomes that must not be retried. The team now replays the policy over scripted outcomes, so every case gets a test.
An assistant wrote retry_decision_trace(outcomes, max_attempts). It is in the editor. It has a bug. Find it and fix it.
Input and output:
outcomes: what the client returns on each attempt, in order. Each is a string: a status code such as"200"or"503","io_error","timeout", or any other text. The list can be empty.max_attempts: the most attempts the wrapper makes, an integer. It can be 0 or negative.- Return the trace of what happened, as a list of strings.
Rules the tests check:
- Attempt 1 uses the first outcome, attempt 2 the second, and so on. Once the list runs out, every later attempt's outcome is
"io_error". - Each attempt adds
"try:<outcome>"to the trace, for example"try:503". - Retryable outcomes are
"io_error","timeout", and any string of exactly 3 digits that starts with5. - Every other outcome is final. That includes every 2xx and every 4xx status, and any other string, such as
"5"or"600". After a final outcome, add"return:<outcome>"and stop. - If every attempt up to
max_attemptswas retryable, add"exhausted"after the last one. - When
max_attemptsis 0 or less, there are no attempts and the trace is["exhausted"].
Examples
retry_decision_trace(outcomes: list[str], max_attempts: int) -> list[str]Example 1
Input
retry_decision_trace(["io_error", "200"], 3)Output
["try:io_error", "try:200", "return:200"]Example 2
Input
retry_decision_trace(["400"], 3)Output
["try:400", "return:400"]Example 3
Input
retry_decision_trace(["503", "503", "503"], 3)Output
["try:503", "try:503", "try:503", "exhausted"]