Fehler
Eine Form, zwei Ebenen und eine Request-ID auf allem.
Der Umschlag
type ist eine feste Menge, auf die Sie verzweigen können und die nie wachsen wird. code ist spezifisch und additiv; behandeln Sie einen, den Sie nicht kennen, als seinen type. requestId steht auf jeder Response, auch auf erfolgreichen, und ist das, was eine Meldung mit einer Logzeile verbindet.
{ "error": { "type": "validation_error", "code": "invalid_email_address", "message": "Not a valid email address: ada@", "param": "to.0", "docUrl": "https://openemail.uk/docs/api/errors#invalid_email_address", "requestId": "req_e103790543af4…" }}param ist mit Punkten und Indizes versehen, sodass es auf genau das Element zeigt (to.0, attachments.2.filename) statt auf das Feld, das es enthält.
Statuscodes
| Status | type | Häufige Codes |
|---|---|---|
| 400 | invalid_request_error | malformed_json, invalid_idempotency_key |
| 401 | authentication_error | missing_api_key, invalid_api_key, revoked_api_key, invalid_credential_type |
| 403 | permission_error | insufficient_scope, from_address_forbidden |
| 404 | not_found_error | resource_not_found |
| 409 | conflict_error | email_not_cancellable, translation_not_configured |
| 422 | validation_error | invalid_email_address, reserved_header, too_many_recipients, unknown_parameter, idempotency_key_reuse, label_not_directly_settable, unknown_language, translation_too_long |
| 429 | rate_limit_error | send_quota_exceeded, too_many_inboxes |
| 500 | api_error | internal_error |
| 503 | api_error | translation_failed |
Ein 404 unterscheidet nie zwischen "existiert nicht" und "gehört zu einem anderen Workspace". Das ist Absicht: Der Unterschied ist selbst eine Information.
Ein 429 trägt nie Retry-After, wählen Sie die Wartezeit also selbst. send_quota_exceeded ist das monatliche Sendekontingent, und es wird am Monatsersten zurückgesetzt – zeigen Sie es also einer Person, statt zurückzufahren. too_many_inboxes ist die Obergrenze für das Erzeugen von Wegwerf-Postfächern, und ein Postfach zu verlängern, das Sie bereits haben, kostet nichts davon.
500 und 503 teilen sich einen type und bedeuten für einen Aufrufer Unterschiedliches. Ein 503 ist eine Abhängigkeit, die nicht geantwortet hat (heute ist das der Übersetzer), und die Anfrage lohnt einen unveränderten erneuten Versuch; ein 500 liegt bei uns und sollte mit seiner requestId gemeldet werden.
Damit umgehen
Verzweigen Sie für das Verhalten auf type und lesen Sie code für die Meldung, die Sie einem Menschen zeigen. Ein unbekannter code ist kein Fehler in Ihrem Client. Er bedeutet, dass wir einen Fehlerfall genauer benannt haben als bisher.
const res = await fetch(`${BASE}/emails`, { method: 'POST', headers, body }); if (!res.ok) { const { error } = await res.json(); switch (error.type) { case 'rate_limit_error': throw new RateLimited(error.code); case 'validation_error': // error.param points at the offending field throw new BadRequest(`${error.param}: ${error.message}`); case 'authentication_error': // revoked_api_key and expired_api_key are worth telling an operator apart throw new AuthFailed(error.code); default: // quote requestId when you report it throw new Unexpected(error.message, error.requestId); }}