Debug an API response before retrying

Separate transport failures, HTTP errors and decoding errors, then choose a safe recovery path.

Capture the evidence

Record method, sanitized URL, timestamp, status, Content-Type and the provider request ID. Keep credentials and personal data out of logs. A resolved fetch promise does not imply a 2xx response; a rejected promise does not prove a write failed to reach the server.

Decode according to the response

Handle 204 before JSON parsing. Inspect non-success bodies as bounded text for diagnosis, and require an expected media type before treating success as JSON. A redirected login page can be 200 HTML. The example below is a small decoder, not a complete retry client.

async function decode(response) {
  if (response.status === 204) return null;
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  const type = (response.headers.get('content-type') || '').split(';')[0].trim();
  if (type !== 'application/json' && !type.endsWith('+json')) throw new Error('Expected JSON');
  return response.json();
}

Choose the recovery by cause

Repair invalid syntax or field values before retrying 400/422. Refresh an expired token through its issuer once; a 403 may require a permission change. For 412, retrieve the current ETag and reconcile changes. For 429/503, honor Retry-After and cap attempts. A 202 needs the documented job-status flow rather than immediate file parsing.

Protect writes

A timeout leaves the outcome uncertain. Persist the provider's documented idempotency key with the operation, reuse it only for identical retries and query the original outcome when possible. Never infer that every API accepts a generic Idempotency-Key header. Do not automatically retry a payment simply because response parsing failed.

Reproduce locally and then verify the integration

Construct Response(null, {status:204}) and a Response containing HTML with status 200 to test decoder branches. Add a 429 fixture with Retry-After: 30 and verify a 30000 ms minimum delay calculation. These tests validate client decisions; a staging integration must still exercise real authentication, rate limits and uncertain write outcomes.

Verification scope

Authored deterministic HTTP examples. Offline tests cover selected Response, Headers, URL, JSON and byte-length behaviors; provider authentication, retries and network outcomes are not executed.

Primary references

Use these scenarios in your workflow

Preview the related 50-record dataset or connect your agent.