エラー
すべての失敗は例外を送出する。クラスは 2 つで、API エラーには必ずリクエスト id が付く。
エラーを捕捉する
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` | リクエストが送信される前に送出される。キーの欠落や書式不正、使用できない baseUrl、ブラウザー環境、空の id などが原因。 |
| ゲッター | true になる条件 |
|---|---|
| `isAuth` | type が authentication_error、すなわち 401 の場合。キーがない、資格情報の種類が違う、あるいは当方が発行していないキーであることを意味する。 |
| `isPermission` | permission_error、すなわち 403 の場合。キー自体は有効だが、必要なスコープまたは From アドレスを持っていない。 |
| `isScopeMissing` | code が insufficient_scope の場合。不足しているスコープを名指しする 403 である。 |
| `isInvalidRequest` | invalid_request_error、すなわち 400 の場合。リクエストを解釈できなかったことを表す。サイズ上限を超えたメッセージは 422 の message_too_large として返るため、それを捕捉するゲッターは isValidation である。 |
| `isValidation` | validation_error、すなわち 422 の場合。スキーマが拒否したことを表し、param が該当フィールドを示す。 |
| `isNotFound` | not_found_error、すなわち 404 の場合。該当するリソースが存在しない。 |
| `isConflict` | conflict_error、すなわち 409 の場合。対象のリソースは、その操作を行える段階をすでに過ぎている。 |
| `isRateLimited` | rate_limit_error、すなわち 429 の場合。サーバーが待機時間を指定していれば retryAfterSeconds にその値が入る。 |
| `isServerError` | status が 500 以上の場合。サポートに問い合わせる際は requestId を伝えること。 |
| `isRetryable` | status が 408、429、500、502、503、504 のいずれかの場合。 |
ゲッターはエンベロープのうち凍結された側である type を読む。code は string のままである。API は code が開かれており追加のみが行われることを保証しているので、見覚えのない値は type として扱えばよい。閉じたユニオンにしてしまうと、新しい失敗の種類を読むたびに SDK のアップグレードが必要になる。
API のエラーエンベロープではないボディも OpenEmailApiError になる。その場合 type はステータスから推定され、code には unrecognised_response が設定される。ボディが JSON でない成功レスポンスでも同じ例外が送出される。
中断も OpenEmailNetworkError になる。リクエストの最中でも、リトライ前の待機中でも同じであり、中断の情報は cause に保持される。自分が行ったキャンセルとネットワーク障害を区別する必要がある場合は signal.aborted を確認すること。
requestId
すべての OpenEmailApiError は、エラーボディまたは x-request-id ヘッダーからサーバーが返したリクエスト id を保持する。これは手元の失敗をサーバーのログの 1 行に結び付ける唯一の手がかりである。成功時に解決されるのはパース済みのボディだけなので、そこから読み取れるリクエスト id はない。