خطاها
هر شکستی throw میشود. دو کلاس، و یک شناسهٔ درخواست روی هر خطای API.
گرفتن یک خطا
import { OpenEmailApiError, OpenEmailNetworkError, openemail } from '@openemail/sdk' try { await openemail.emails.send(message)} catch (error) { if (error instanceof OpenEmailApiError) { if (error.isValidation) console.error(error.code, error.param, error.message) if (error.isPermission) console.error(await openemail.addresses.list()) if (error.isRateLimited) console.error('try again in', error.retryAfterSeconds, 'seconds') console.error(error.status, error.requestId) } if (error instanceof OpenEmailNetworkError && error.isTimeout) console.error('no answer in time') throw error}یک permission_error روی ارسال معمولاً به اسکوپ ارسالِ خودِ کلید برمیگردد، به دامنه یا آدرسی که به آن داده نشده، نه به فضای کاری؛ و به همین دلیل است که نمونه چاپ میکند addresses.list() میگوید این کلید از چه آدرسهایی میتواند بفرستد.
کلاسها
| کلاس | چه زمانی |
|---|---|
| `OpenEmailApiError` | API پاسخ داده است، اما نه با موفقیت. حامل status، type، code، param، docUrl، requestId و retryAfterSeconds است. |
| `OpenEmailNetworkError` | هیچ پاسخی نرسیده است: DNS، TLS، قطع شدن اتصال، تایماوت، یا AbortSignal خودتان. حامل cause است و وقتی دلیل، تایماوت بوده باشد isTimeout برابر true است. |
| `Error` | پیش از آنکه چیزی فرستاده شود throw میشود: کلیدِ نبوده یا بدشکل، یک baseUrl غیرقابلاستفاده، یک مرورگر، یک شناسهٔ خالی. |
| گتر | چه زمانی true است |
|---|---|
| `isAuth` | type برابر authentication_error است، یک 401 Unauthorized: نبودن کلید، نوع نادرست اعتبارنامه، یا کلیدی که ما صادرش نکردهایم. |
| `isPermission` | permission_error، یک 403 Forbidden: کلیدی واقعی بدون اسکوپ یا بدون آدرس From مورد نیازش. |
| `isScopeMissing` | code برابر insufficient_scope است، همان 403 Forbidden که اسکوپ غایب را نام میبرد. |
| `isInvalidRequest` | invalid_request_error، یک 400 Bad Request: درخواستی که قابل فهم نبوده است. پیامی فراتر از سقف اندازه بهصورت 422 با message_too_large برمیگردد، پس isValidation گتری است که آن را میگیرد. |
| `isValidation` | validation_error، یک 422: اسکیما آن را نپذیرفته است و param نام فیلد را میگوید. |
| `isNotFound` | not_found_error، یک 404 Not Found: چنین منبعی وجود ندارد. |
| `isConflict` | conflict_error، یک 409 Conflict: منبع از نقطهای گذشته است که بتوان این کار را روی آن انجام داد. |
| `isRateLimited` | rate_limit_error، یک 429 Too Many Requests. وقتی سرور مدتی را نام برده باشد، retryAfterSeconds آن انتظار را نگه میدارد. |
| `isServerError` | status برابر 500 یا بالاتر است. اگر با پشتیبانی تماس گرفتید، requestId را ذکر کنید. |
| `isRetryable` | status یکی از 408، 429، 500، 502، 503 یا 504 است. |
گترها type را میخوانند، یعنی نیمهٔ ثابتِ پاکت. code یک string باقی میماند، چون API تضمین میکند که باز و افزایشی است؛ پس کدی را که نمیشناسید مطابق type آن رفتار کنید. یک union بسته، بهای خواندن یک حالت شکست تازه را به ارتقای SDK تبدیل میکرد.
بدنهای که پاکت خطای API نباشد باز هم به OpenEmailApiError تبدیل میشود، با type استنتاجشده از status و code برابر unrecognised_response. پاسخ موفقی که بدنهاش JSON نباشد نیز همین خطا را throw میکند.
یک abort هم OpenEmailNetworkError است، چه در میانهٔ درخواست رخ دهد چه در انتظار پیش از یک تلاش مجدد، و خودِ abort روی cause نگه داشته میشود. هر جا لازم شد لغو خودتان را از یک خطای شبکه تشخیص دهید، signal.aborted را بررسی کنید.
requestId
هر OpenEmailApiError شناسهٔ درخواستی را که سرور فرستاده است با خود دارد، از بدنهٔ خطا یا از هدر x-request-id، و تنها چیزی است که شکست شما را به یک سطر در لاگ سرور گره میزند. یک پاسخ موفق تنها به بدنهٔ تجزیهشده resolve میشود، پس روی آن شناسهٔ درخواستی برای خواندن وجود ندارد.