خطاها
یک شکل، دو سطح، و یک شناسهٔ درخواست روی همه چیز.
پوشش خطا
type مجموعهای منجمد است که میتوانید روی آن شاخه بزنید و هرگز بزرگ نمیشود. code مشخص و افزودنی است، پس هر کدی را که نمیشناسید همان type آن به شمار آورید. requestId روی هر پاسخی هست، از جمله پاسخهای موفق، و همان است که یک گزارش را به یک خط لاگ گره میزند.
{ "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 نقطهدار و اندیسدار است، پس بهجای فیلدی که آن را در بر دارد به خودِ همان عنصر اشاره میکند (to.0، attachments.2.filename).
کدهای وضعیت
| وضعیت | type | کدهای رایج |
|---|---|---|
| 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 |
یک 404 هرگز «وجود ندارد» را از «متعلق به فضای کاری دیگری است» جدا نمیکند. این عمدی است: خودِ همین تفاوت، اطلاعات است.
یک 429 هرگز Retry-After با خود ندارد، پس زمان انتظار را خودتان انتخاب کنید. send_quota_exceeded سهمیهٔ ماهانهٔ ارسال است و اول هر ماه بازنشانی میشود، پس بهجای عقبنشینی آن را به یک آدم نشان دهید. too_many_inboxes سقف ضرب صندوقهای یکبارمصرف است، و تمدید صندوقی که از پیش دارید هیچ هزینهای روی آن ندارد.
500 و 503 یک type مشترک دارند و برای فراخوان معنای متفاوتی دارند. 503 یعنی وابستگیای پاسخ نداده (امروز یعنی مترجم)، و درخواست ارزش تلاش دوبارهٔ بیتغییر را دارد؛ 500 از آنِ ماست و ارزش دارد با requestId آن گزارش شود.
رسیدگی به آنها
برای رفتار روی type شاخه بزنید و code را برای پیامی که به یک آدم نشان میدهید بخوانید. code ناشناخته خطایی در کلاینت شما نیست. یعنی ما شکستی را دقیقتر از گذشته نامگذاری کردهایم.
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); }}