Guías

Error handling

The body says what happened. Discarding it is the most expensive mistake you can make against this API.

  1. 1

    Read the body, not just the status

    A validation 400 carries `issues` with the exact field that was refused. Without it, a type error on one field is indistinguishable from a permissions problem.

    javascript
    const res = await fetch(url, options);
    
    if (!res.ok) {
      const detail = await res.json().catch(() => ({}));
    
      if (detail.issues) {
        for (const i of detail.issues) console.error(`${i.path}: ${i.message}`);
      }
    
      throw new Error(`${detail.error ?? res.status}: ${detail.message ?? ""}`);
    }
  2. 2

    Respect Retry-After on a 429

    Retrying in a loop against a rate limit only extends the block.

    javascript
    if (res.status === 429) {
      const wait = Number(res.headers.get("Retry-After") ?? 60);
      await new Promise((r) => setTimeout(r, wait * 1000));
    }

A retry can duplicate. Writes are not idempotent: if a POST is cut off after creating and you retry it, you end up with two resources. Store the id the first response returns and check before retrying.