Fix the decision trace of a retry helper

Review the AI's codeMedium15 min

Your task

An agent's Java retry helper, copied into several services, caught every exception, retried it with no delay and returned null when it ran out of attempts. You are replacing it, and you describe the new helper's behavior as a trace of what it does so each choice can be tested.

An assistant wrote retry_plan(attempt_results, max_attempts, base_delay_ms, max_delay_ms). It is in the editor. It has a bug. Find it and fix it.

Input and output:

  • attempt_results: what each call returns, in order: "ok", "retryable", "fatal" or anything else (an error nobody classified).
  • max_attempts: the most calls the helper makes.
  • base_delay_ms, max_delay_ms: the first sleep and the cap on every sleep, in milliseconds.
  • Return the trace as a list of strings.

Rules the tests check:

  • A negative base_delay_ms or max_delay_ms counts as 0. The first sleep is the smaller of the two. Each later sleep is double the one before, but never more than max_delay_ms.
  • If max_attempts is 0 or less, the trace is just ["throw:exhausted"].
  • Otherwise make calls in order. A call past the end of attempt_results returns "retryable". For each call, add "try:<result>", then:
    • "ok": add "return:ok" and stop.
    • "fatal": add "throw:non_retryable" and stop.
    • "retryable": if this was call number max_attempts, add "throw:exhausted" and stop. Otherwise add "sleep:<ms>" and make the next call.
    • anything else: add "throw:unclassified" and stop. Only results classified as retryable are retried.

Examples

retry_plan(attempt_results: list[str], max_attempts: int, base_delay_ms: int, max_delay_ms: int) -> list[str]
Example 1
Inputretry_plan(["retryable", "ok"], 3, 100, 1000)
Output["try:retryable", "sleep:100", "try:ok", "return:ok"]
Example 2
Inputretry_plan(["fatal"], 3, 100, 1000)
Output["try:fatal", "throw:non_retryable"]
Example 3
Inputretry_plan(["retryable", "retryable", "retryable"], 3, 100, 250)
Output["try:retryable", "sleep:100", "try:retryable", "sleep:200", "try:retryable", "throw:exhausted"]