Pre-commit Review
Review all changes before committing. Read more
You’re adding code that calls an external API, a third-party service, or a database. These integrations are where production incidents often start. A missing timeout, an unbounded retry loop, or no error handling can take down your service when the external dependency misbehaves.
This guide shows how to use Unfault to catch these patterns before they ship.
When code calls external services, a few patterns cause most of the problems:
Missing timeouts: The external service hangs. Your request hangs. Your thread pool fills up. Your service stops responding.
Unbounded retries: The external service returns errors. Your code retries forever. You amplify the problem and possibly get rate limited.
No circuit breaker: The external service is down. Every request tries to reach it, fails, and takes the slow timeout path. Your service becomes unusably slow.
Swallowed errors: Something fails. The error gets caught and ignored. Debugging becomes archaeology.
No correlation IDs: A request fails somewhere in the chain. You can’t trace what happened across services.
Unfault detects all of these.
After writing code that connects to an external service:
unfault review --uncommitted --dimension stabilityThe --dimension stability flag focuses on the patterns most relevant to external integrations.
Example output:
High: Missing HTTP timeout src/integrations/billing.py:42 HTTP request without timeout can hang indefinitely
High: Missing circuit breaker src/integrations/billing.py:38 External service call without circuit breaker Prerequisites: request classification, metrics collection
Medium: No retry logic src/integrations/billing.py:42 HTTP call may fail transiently without retryNot every finding requires immediate action. Here’s how to think about them:
Almost always worth adding. This is a low-effort, high-impact fix:
# Beforeresponse = requests.get(url)
# Afterresponse = requests.get(url, timeout=30.0)Worth adding for idempotent operations. Be careful with non-idempotent ones:
# Safe for GET requests@retry(stop=stop_after_attempt(3), wait=wait_exponential())def fetch_data(): return requests.get(url, timeout=30.0)
# Be careful with POST requests that aren't idempotentThese require more infrastructure. If Unfault reports prerequisites are missing (metrics, request classification), this is a note for future work, not something to implement in this PR.
If Unfault reports empty catch blocks or swallowed exceptions, add appropriate handling:
# Beforetry: response = client.fetch()except Exception: pass # Empty catch
# Aftertry: response = client.fetch()except RequestException as e: logger.error("Failed to fetch from billing service", error=str(e)) raise BillingServiceError("Could not reach billing service") from eWrite the integration code
Get it working first.
Review for stability patterns
unfault review --uncommitted --dimension stabilityAdd timeouts
These are almost always worth adding.
Add error handling
Make sure errors are logged and propagated appropriately.
Consider retries
For idempotent operations on flaky services.
Note infrastructure gaps
If Unfault suggests circuit breakers or rate limiting but prerequisites are missing, document this for future work.
Review again
unfault review --uncommitted --dimension stabilityConfirm the high-severity findings are addressed.
When an AI assistant writes integration code, it often forgets these operational concerns. Add to your AGENTS.md:
When writing code that calls external services:
1. Always include timeouts on HTTP calls2. Consider retry logic for idempotent operations3. Log errors with enough context to debug later4. After writing, run: unfault review --uncommitted --dimension stability5. Address high-severity findings before committingSee Use with AI Agents for full setup instructions.
Before writing new integration code, see how similar integrations work in your codebase:
unfault ask "How do we call external APIs in this project?"unfault ask "What's our retry strategy for HTTP calls?"Or find files that already use HTTP clients:
unfault graph library requestsunfault graph library httpxThis helps you match existing conventions rather than inventing new patterns.