高度なエラー処理
HTTP レベルのエラーを理解する方法をご紹介します。
このページでは、次の 2 種類の高度なエラー処理に関するトピックについて説明します。
この情報が該当しない場合もあります。Stripe の公式の SDKは、HTTP および再試行に関する情報を多く扱っています。クライアントライブラリを使用する場合は、こちらから開始できます。
HTTP のエラー
API コールが失敗した場合でも、クライアントライブラリでは、例外を発生させるか、エラーの値を返すことでエラー情報を提供します。しかし、クライアントライブラリを使用しない場合、または異常な状況が発生した場合は、HTTP レスポンスと送信のタイミングに関する低レベルの詳細が必要になることがあります。
HTTP の観点から、エラーは次の 3 つの主要なカテゴリーに分類されます。
各タイプのエラーには、異なる対応とべき等のセマンティクスが必要になります。このページの最後には、レスポンスコードの一覧とその意味が示されています。
コンテンツエラー
コンテンツエラーは、API リクエストのコンテンツが無効な場合に発生し、4xx
のレスポンスコードを含む HTTP レスポンスが返されます。たとえば、無効な API キーが指定された場合は API サーバーから 401
が返され、必須パラメーターが欠落している場合は 400
が返されます。システムは元のリクエストを修正して再試行する必要があります。ユーザーエラー (カードの支払い拒否など) のタイプによっては、プログラムで問題に対処できることがあります。この場合は、システムが適切に対処できるように code
フィールドを含めてください。詳細については、エラーコードをご覧ください。
べき等キーを使用する POST
操作の場合、API メソッドが実行を開始している限り、リクエストの結果に関わらず Stripe の API サーバーは結果をキャッシュします。400
を返すリクエストは、同じべき等キーを持つ新しいリクエストが続く場合、同じ 400
を送り返します。正常な結果を得るために元のリクエストを変更する際は、新しいべき等キーを生成してください。この操作にはいくつかの注意点があります。たとえば、429
でレート制限されたリクエストは、API のべき等レイヤーの前にレートリミッタが実行されるため、同じべき等キーで別の結果になる可能性があります。API キーを省略した 401
、または無効なパラメータを送信したほとんどの 400
番台についても同様です。それでも、4xx
エラーに関する最も安全な戦略は、常に新しいべき等キーを生成することです。
ネットワークエラー
ネットワークエラーは、クライアントとサーバー間の通信問題の結果として発生し、ソケット例外やタイムアウト例外などの詳細レベルのエラーを返します。たとえば、クライアントが Stripe のサーバーから読み取りを行う際にタイムアウトしたり、接続が途中で切断されたため API レスポンスが受信されない場合があります。ネットワークエラーは、接続の問題を解決すれば成功する「ように見えますが」、断続的な問題に別のタイプのエラーが隠されている場合があります。
このクラスのエラーは、べき等キーとリクエスト再試行の値が最も明白です。断続的な問題が発生すると、クライアントは通常、サーバーがリクエストを受信したかを確認できない状態になります。明確な回答を得るには、サーバーから結果を受信できるまで、同じべき等キーとパラメーターを使用してそのリクエストを再試行する必要があります。異なるパラメーターで同じべき等を送信すると、新しいリクエストが元のリクエストと一致しなかったことを示すエラーが発生します。
クライアントライブラリの多くは、べき等キーを生成してリクエストを自動的に再試行できますが、そのためには設定が必要です。クライアントライブラリは最初の失敗の直後に最初の再試行を実行しますが、その後の再試行は、単一の失敗はランダムに発生することが多く、同じ失敗が繰り返されるパターンは長期的な問題が発生しているという想定に基づいて、指数バックオフのスケジュールに従って実行されます。
サーバーエラー
サーバーエラーは、Stripe サーバーの問題により発生し、5xx
エラーコードを含む HTTP レスポンスを返します。これらのエラーは処理が最も困難であり、Stripe は可能な限りこのエラーが発生しないように努めていますが、優れた組み込みではエラーが発生しても処理することができます。
ユーザーエラーと同様に、べき等レイヤーはサーバーエラー (具体的には内部サーバーエラーである 500
番台) を引き起こす POST
ミューテーションの結果をキャッシュするため、同じべき等キーでそれらを再試行すると、通常同じ結果になります。クライアントは新しいべき等キーを使用してリクエストを再試行できますが、元のキーによって副次的効果が発生している可能性があるため、お勧めしません。
結果が 500
のリクエストは不確定なものとして扱う必要があります。このエラーが確認される可能性が最も高いのは、本番環境でインシデントが発生している時であり、通常はそのインシデントの修復時です。Stripe のエンジニアは失敗したリクエストを調査し、500
番台のエラーを引き起こしたミューテーションの結果を適切に照合します。これらのリクエストに対してべき等にキャッシュされたレスポンスは変わりませんが、Stripe の照合の一環として作成された新しいオブジェクトに対して Webhook の実行を試みます。システムに加えられた遡及的な変更の正確な性質は、リクエストのタイプによって大きく異なります。たとえば、支払いの作成で 500
エラーが返された際に、その情報が支払いネットワークをすでに通過したことが検出された場合、Stripe はその支払いのロールフォワードを試行します。そうでない場合はロールバックを試行します。これで問題が解決しない場合は、ユーザーにも認識可能な副次的影響を引き起こす 500
エラーを持つリクエストがお客様に表示される場合があります。
注意
500
エラーを返すリクエストは不確定なものとして扱います。Stripe はこの不完全な状態を最も適切な方法で照合し、また作成された新規オブジェクトに対する Webhook の実行を試みますが、常に最善の結果が得られるわけではありません。
最も広範囲の 500
番台をシステムで処理するためには、通常の API レスポンスでは受信することがない Event オブジェクトを受信できるように Webhook ハンドラを設定します。このような新しいオブジェクトをシステムのローカル状態のデータと相互参照するための 1 つの手法は、API で新しいリソースを作成するときに、Metadata (メタデータ)を持つローカル識別子を送信することです。その識別子は、Webhook が後で照合の一部として生成される場合でも、Webhook を介して送信されるオブジェクトのメタデータフィールドに表示されます。
べき等
べき等とは、同じ操作を何度繰り返しても、初回の試行と同じ結果が得られるという性質として定義された Web API 設計原理です。特に、最初のリクエストがネットワークエラーで応答を得られなかった場合などに、API リクエストの再試行を安全に行うことができます。一定量の断続的なエラーは想定されるため、クライアントには失敗したリクエストをサーバーと照合する方法が必要であり、べき等がそのメカニズムを提供します。
多くのクライアントライブラリは、べき等キーを生成してリクエストを自動的に再試行できますが、そのための設定を行う必要があります。再試行をより細かく制御するには、べき等キーを生成して、再試行のための独自のロジックを作成します。
GET および DELETE リクエスト
Stripe API では、GET
および DELETE
リクエストのべき等性を保証しているため、常に安全に再試行することができます。
POST リクエスト
べき等キーを含めると、POST
リクエストがべき等性を持つようになり、API は重複操作を避けるために必要な記録の保持を行います。最初にキーを受け取ってから 24 時間以内に 2 回目のリクエストが発生していれば、クライアントはべき等キーを含むリクエストを安全に再試行できます (キーは 24 時間後に有効期限が切れます)。たとえば、オブジェクトを作成するリクエストがネットワーク接続エラーのために応答しない場合には、クライアントが同じべき等キーを使用してリクエストを再試行すれば、重複したオブジェクトが作成されることはありません。
べき等キーの送信
べき等キーは、Idempotency-Key
ヘッダーで送信されます。これを Stripe API へのすべての POST
リクエストで使用します。ほとんどの公式クライアントライブラリでは、再試行の送信が設定されていれば、自動的に送信できます。
べき等キーを手動で送信する場合には、使用するトークンが十分に一意であり、過去 24 時間にわたってお客様のアカウント内で 1 つの操作を一義的に識別できるようにしてください。以下にべき等キーを生成する一般的な方法を 2 通り例示します。
- UUID v4 など、十分にランダムなトークンが生成されるアルゴリズムを使用する。
- ショッピングカートの ID など、ユーザーに関連付けられたオブジェクトからキーを派生させる。これは、重複した送信を回避するための比較的シンプルな方法です。
サーバーから再試行しようとしている、以前に実行されたレスポンスを識別するには、Idempotent-Replayed: true
というヘッダーを探します。
Stripe-Should-Retry ヘッダー
クライアントライブラリは、ステータスコードやレスポンス本文の内容だけでは、再試行すべきかどうかを判断でない場合があります。API はリクエストが再試行可能であるという追加情報を得た場合、Stripe-Should-Retry
ヘッダーを指定してレスポンスを返します。
Stripe-Should-Retry
をtrue
に設定している場合は、クライアントがリクエストを再試行する必要があります。ただしクライアントは、API に過度な負荷をかけないように、次のリクエストを行う前に (おそらく指数バックオフのスケジュールに従って決定される) 一定の時間待つ必要があります。Stripe-Should-Retry
をfalse
に設定している場合は、それ以上の効果がないためクライアントはリクエストを再試行「しないでください」。- レスポンスに
Stripe-Should-Retry
が設定されていない場合は、API はリクエストを再試行できるかどうかを判断できません。クライアントは、レスポンスの他のプロパティ (ステータスコードなど) にフォールバックして判断する必要があります。
Stripe のクライアントライブラリに組み込まれている再試行のメカニズムは、自動的に Stripe-Should-Retry
に従います。これらのいずれかを使用している場合、手動で処理する必要はありません。
HTTP ステータスコードリファレンス
200 | OK | すべてが想定どおりに動作しました。 |
400 | Bad Request | リクエストは受け入れられませんでした。多くの場合、必要なパラメーターが足りないことが理由として考えられます。 |
401 | 無許可 | 有効な API キーが入力されていません。 |
402 | Request Failed | パラメーターは有効でしたがリクエストが失敗しました。 |
403 | Forbidden | API キーにリクエストを実行する権限がありません。 |
409 | Conflict | リクエストが他のリクエストと競合しています (同じべき等キーを使用していることが理由として考えられます)。 |
429 | Too Many Requests | 短時間での API へのリクエスト数が多すぎます。リクエストの指数バックオフを推奨します。 |
500、502、503、504 | サーバーエラー | Stripe 側で問題が発生しました。 |