Should a FHIR client retry every 500 response?
Only with a bounded policy and only when the operation is safe to repeat. Consider server guidance, idempotency, elapsed time, and an overall retry budget.
Production-grade access is free with an account. · Synthetic demo · no account needed
Patient-authorized EHR integration
A production integration needs a failure model that separates authentication, authorization, unsupported behavior, source outages, and incomplete synchronization.
Updated: 2026-08-25 · 10 min read
Retry only transient and safely repeatable work, honor server guidance, parse OperationOutcome when present, and expose partial sync state. An integration is more trustworthy when it reports incomplete data than when it silently returns an empty record.
Evidence boundary: Uses FHIR R4 HTTP and OperationOutcome semantics with conservative distributed-systems retry practices.
Author: FinchNode Engineering
| Outcome | Likely interpretation | Default action |
|---|---|---|
| 200 with zero entries | Successful search with no matches | Record empty result and freshness |
| 400 + OperationOutcome | Invalid or unsupported request | Do not retry unchanged; inspect issue details |
| 401 | Missing or expired authorization | Refresh once or require reauthorization |
| 403 | Granted access does not permit request | Mark category unavailable; do not loop |
| 404 | Resource or endpoint unsupported/not found | Check capability and route |
| 429 | Rate limited | Honor Retry-After and retry budget |
| 5xx / timeout | Transient source or network failure | Bounded retry with jitter |
export async function withRetry<T>(operation: () => Promise<T>, attempts = 4) {
let lastError: unknown;
for (let attempt = 0; attempt < attempts; attempt += 1) {
try {
return await operation();
} catch (error) {
lastError = error;
if (!isTransient(error) || attempt === attempts - 1) throw error;
const base = Math.min(500 * 2 ** attempt, 8_000);
const jitter = Math.floor(Math.random() * 250);
await new Promise((resolve) => setTimeout(resolve, base + jitter));
}
}
throw lastError;
}
Only with a bounded policy and only when the operation is safe to repeat. Consider server guidance, idempotency, elapsed time, and an overall retry budget.
It is the standard FHIR resource for reporting issues, errors, warnings, and diagnostics. Parse it when present, but still handle non-FHIR error bodies safely.
No. A searchset Bundle with zero matching entries is normally a successful empty result. Preserve the distinction between empty, unsupported, unauthorized, and failed.
Show which sources and categories succeeded, their freshness, and which remain unavailable or syncing. Do not present a partial record as complete.