Błędy
Każda porażka rzuca wyjątek. Dwie klasy i identyfikator żądania przy każdym błędzie API.
Przechwytywanie błędu
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 przy wysyłce to zwykle zakres wysyłki KLUCZA, domena albo adres, których mu nie nadano, a nie przestrzeń robocza; dlatego przykład wypisuje to, co addresses.list() mówi o adresach, z których ten klucz może wysyłać.
Klasy
| Klasa | Kiedy |
|---|---|
| `OpenEmailApiError` | API odpowiedziało, ale nie powodzeniem. Niesie status, type, code, param, docUrl, requestId i retryAfterSeconds. |
| `OpenEmailNetworkError` | Żadna odpowiedź nie dotarła: DNS, TLS, zerwane połączenie, timeout albo Twój własny AbortSignal. Niesie cause, a isTimeout jest true, gdy powodem był timeout. |
| `Error` | Rzucany, zanim cokolwiek wyjdzie: brakujący albo źle sformułowany klucz, nieużywalny baseUrl, przeglądarka, pusty identyfikator. |
| Getter | True, gdy |
|---|---|
| `isAuth` | type to authentication_error, czyli 401: brak klucza, niewłaściwy rodzaj poświadczenia albo klucz, którego nie wydaliśmy. |
| `isPermission` | permission_error, czyli 403: prawdziwy klucz bez potrzebnego zakresu albo adresu From. |
| `isScopeMissing` | code to insufficient_scope, czyli 403 nazywające brakujący zakres. |
| `isInvalidRequest` | invalid_request_error, czyli 400: żądanie, którego nie dało się zrozumieć. Wiadomość powyżej limitu rozmiaru wraca jako 422 message_too_large, więc getterem, który ją łapie, jest isValidation. |
| `isValidation` | validation_error, czyli 422: schemat ją odrzucił, a param nazywa pole. |
| `isNotFound` | not_found_error, czyli 404: nie ma takiego zasobu. |
| `isConflict` | conflict_error, czyli 409: zasób jest już za punktem, w którym można było mu to zrobić. |
| `isRateLimited` | rate_limit_error, czyli 429. retryAfterSeconds niesie czas oczekiwania, gdy serwer go podał. |
| `isServerError` | status to 500 lub więcej. Podaj requestId, gdy kontaktujesz się ze wsparciem. |
| `isRetryable` | status to 408, 429, 500, 502, 503 albo 504. |
Gettery czytają type, czyli zamrożoną połowę koperty. code pozostaje ciągiem znaków, bo API gwarantuje, że jest otwarty i przyrostowy, więc nierozpoznany traktuj jak jego type. Zamknięta unia sprawiłaby, że ceną za odczytanie nowego trybu porażki byłaby aktualizacja SDK.
Treść, która nie jest kopertą błędu API, i tak staje się OpenEmailApiError, z type wywnioskowanym ze statusu i code ustawionym na unrecognised_response. Powodzenie, którego treść nie jest JSON-em, też rzuca taki błąd.
Przerwanie również jest OpenEmailNetworkError, niezależnie od tego, czy nastąpi w trakcie żądania, czy w trakcie oczekiwania przed ponowieniem, a samo przerwanie jest zachowane w cause. Sprawdź signal.aborted, gdy musisz odróżnić własne anulowanie od awarii sieci.
requestId
Każdy OpenEmailApiError niesie identyfikator żądania przysłany przez serwer, z treści błędu albo z nagłówka x-request-id, i jest jedyną rzeczą wiążącą Twoją porażkę z linią w logu serwera. Powodzenie rozwiązuje się samą sparsowaną treścią, więc nie ma na nim identyfikatora żądania do odczytania.