Fix the retry policy behind an HTTP client wrapper

Review the AI's codeEasy12 min

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 with 5.
  • 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_attempts was retryable, add "exhausted" after the last one.
  • When max_attempts is 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
Inputretry_decision_trace(["io_error", "200"], 3)
Output["try:io_error", "try:200", "return:200"]
Example 2
Inputretry_decision_trace(["400"], 3)
Output["try:400", "return:400"]
Example 3
Inputretry_decision_trace(["503", "503", "503"], 3)
Output["try:503", "try:503", "try:503", "exhausted"]