Go
エラーと再試行
あらゆる失敗に 1 つのエラー型、種類ごとに 1 つのセンチネル、そして二重に送信しない再試行。
エラーの処理
_, err := client.Emails.Send(ctx, openemail.Body{ "from": "[email protected]", "to": "[email protected]", "subject": "Your September invoice", "text": "Invoice attached.",}) var failure *openemail.Error switch {case err == nil: fmt.Println("sent")case errors.Is(err, openemail.ErrValidation): errors.As(err, &failure) fmt.Println(failure.Code, failure.Param, failure.Message)case errors.Is(err, openemail.ErrRateLimited): errors.As(err, &failure) fmt.Println("try again in", failure.RetryAfter)case errors.Is(err, openemail.ErrTimeout): fmt.Println("no answer in time")default: return err}すべての失敗は *openemail.Error です。errors.Is で種類がわかり、errors.As で API が返した内容を含むエラーそのものを取得できます。
| 項目 | 内容 |
|---|---|
| Status | HTTP ステータス。応答が届かなかった場合は 0 です。 |
| Type, Code | API のエラー型とコード。たとえば validation_error と invalid_parameter です。 |
| Param | 原因となったフィールド。ある場合のみです。 |
| RequestID | サポートに連絡するときに伝える id です。 |
| DocURL | そのコードを説明するドキュメントのページです。 |
| RetryAfter | API が待つよう求めた時間。 |
| Fields | 登録フォームが拒否したフィールド。それぞれに Key と Error があります。 |
| Body | デコードされたレスポンスボディです。 |
失敗の種類
| センチネル | 一致する場合 |
|---|---|
| ErrAuthentication | キーまたはトークンが拒否されました。401 です。 |
| ErrPermission | この資格情報ではその操作が許可されていません。403 です。 |
| ErrScopeMissing | 呼び出しに必要なスコープが資格情報にありません。 |
| ErrStepUpRequired | アクセストークンは先にコードを検証する必要があります。 |
| ErrNotFound | その id を持つものがありません。404 です。 |
| ErrConflict | 変更が現在の状態と競合しています。409 です。 |
| ErrValidation | フィールドが拒否されました。422 です。 |
| ErrRateLimited | リクエストが多すぎるか、割り当てを使い切りました。429 です。 |
| ErrInvalidRequest | リクエストに対するそれ以外の拒否です。 |
| ErrServer | API が失敗しました。ステータスは 500 以上です。 |
| ErrRetryable | クライアントが再試行するステータスです。 |
| ErrNetwork | 応答が届きませんでした。 |
| ErrTimeout | タイムアウトまでにレスポンスが届きませんでした。 |
| ErrInvalidArgument | 呼び出しそのものに誤りがあり、何も送信されませんでした。 |
| ErrWebhookSignature | Webhook の配信が検証に失敗しました。 |
キャンセルされたコンテキストは引き続き context.Canceled に一致し、期限切れは context.DeadlineExceeded に一致します。
再試行されるもの
- 読み取り、送信、繰り返しても安全なすべての書き込みは、最大
WithMaxRetries回まで再試行されます。それ以外の書き込みは 1 回だけ送信されます。 - ステータス 408、500、502、503、504 は、0.5 秒から始まり 8 秒まで倍増する待ち時間をはさんで再試行されます。
- 429 は、1 分以内の
Retry-Afterが付いている場合にだけ再試行され、クライアントはその時間だけ待ちます。 - 失敗した接続やタイムアウトした接続も同じように再試行されます。
再試行される送信は毎回同じ冪等性キーを持つため、API は 2 通目を送らずに最初のメッセージを再生します。