~/teardowns/TD-046.md
←Back to teardowns
# TD-046MediumRuntime

The Retry Loop That Swallowed the Reason

bare except: pass hides the real failure

Published Oct 29, 2026

Executive Summary

A vibe-coded payment retry loop wraps the charge in bare except: pass. It never crashes — but it also never learns why the charge failed. A one-character typo and a gateway outage produce the same silent outcome: three attempts, then None, with nothing logged.

The Prompt

“Add error handling around the payment retry loop so it never crashes.”

The Flaw

bare except: pass swallows every exception — the real gateway error, but also typos, AttributeErrors, and KeyboardInterrupt. The loop never crashes, but it also never learns why the charge failed: a coding bug is indistinguishable from a provider outage. After three attempts it returns None, and the order silently fails with nothing in the logs to diagnose it.

Risk & Impact

[Correctness] Payments fail silently. A one-character typo in gateway.charge produces the same outcome as a provider outage — and there is no log to tell them apart.

Cost: Undiagnosable payment failures that only surface as angry customers and unprocessed orders.

Code Comparison

❌ Vulnerable (AI generated)

payment.pypython
1
2
3
4
5
6
7
8
def retry_payment(order):
for attempt in range(3):
try:
return gateway.charge(order)
except:
pass # swallow everything, try again
return None

The Fix

Catch the specific, retryable exception type — log it — and raise loudly when retries are exhausted. Never bare except, never pass.

Prevention

  • [linter] flake8-bugbear (B001) and pylint (W0702/W0703) flag bare except and except: pass.
  • [ci] A test that raises a non-transient error must NOT be retried and must raise — proving the loop only retries what it should.
  • [manual] Define the failure mode for each except clause (rule 2): what is retryable, what is fatal, and where the log goes.

Why This Happened

Root cause: the prompt omitted Rule 2 — the guardrails that would have caught this. See the full guide →

Sources

Is your codebase vulnerable to this?

Run Diagnostic on My Project →