Boxアプリケーションで予期せぬエラーが発生したり、断続的に動作が不安定になったり、リクエストの処理が停止したりする場合は、根本原因を特定するための体系的なワークフローが必要です。このガイドでは、Boxのエラーレスポンスの読み方、再試行のタイミングと方法、適切なタイムアウトの設定方法、そして各ステップで使用するBox提供ツールの選択方法など、そのワークフローについて解説します。
体系的なアプローチ
Box APIのエラーのほとんどは、無効なトークン、スコープの欠落、アプリがアクセスできない項目、形式が正しくないリクエスト、あるいは一過性のサーバー側の問題といった、ごく少数の原因のいずれかに起因しています。コードを変更する前に、エラーが発生している処理の流れを、個別にテスト可能な、小さな単位に分割してください。
- 認証。アプリでアクセストークンを取得できますか? そのトークンは、使用している認証方式 (OAuth 2.0、JWT、またはクライアント資格情報許可) に適合したタイプですか?
- 承認。トークンには、エンドポイントが必要とするスコープが含まれていますか? サービスアカウントやユーザーは、対象の項目にアクセスできますか?
- リクエストの作成。URL、HTTPメソッド、ヘッダーの設定、および本文は、APIリファレンスで指定されている内容と完全に一致していますか?
- サーバーのレスポンス。どのようなHTTPステータスコードとBoxエラーコードが返されましたか? 一過性のエラーであった場合、リクエストは正しく再試行されましたか?
- ダウンストリームへの副次的影響。Webhookやワーカーから他のシステムを呼び出した場合、正常に実行されましたか?
アプリケーションのコードを詳しく調べる前に、curlやPostmanなどのツールを使用して、各ステップを個別にテストしてください。
APIレスポンスの調査
Boxは、ほとんどの4xxおよび5xxレスポンスに対して、構造化されたエラーオブジェクトを返します。レスポンス本文とレスポンスヘッダーは必ずログに記録してください。これらは、収集できる最も有用な証拠となります。
{
"type": "error",
"status": 403,
"code": "access_denied_insufficient_permissions",
"help_url": "https://developer.box.com/guides/api-calls/permissions-and-errors/common-errors/",
"message": "Access denied - insufficient permission",
"request_id": "abcdef123456"
}
フィールドは次のように使用します。
| フィールド | フィールドの意味 |
|---|
status | HTTPステータスコード。大まかなカテゴリ (認証、権限、見つからない、レート制限、サーバーエラー) を示します。 |
code | Box固有のエラーコード。を使用して、このエラーの解決策を確認します。 |
message | 人間が理解できる説明文。多くの場合、検証に失敗した具体的なフィールドや値が含まれます。 |
help_url | このエラーに関するドキュメントへの直接リンク。 |
request_id | リクエストの失敗を示す一意の識別子。サポートチケットには必ずこれを記載してください。 |
Box APIのレスポンスのほとんどには、box-request-idというレスポンスヘッダーも含まれています。これは、エラー本文内のrequest_idフィールドとは異なる値です。可能であれば、両方を取得してください。
HTTPステータスごとのBoxエラーコードの詳細なリストについては、を参照してください。
再試行とタイムアウトの処理
すべてのエラーが恒久的なものとは限りません。一過性のエラーに対しては再試行を行うことが適切ですが、恒久的なエラーに対しては、処理を中止して呼び出し元にその旨を通知する方が適切です。恒久的なエラーに対して再試行を行うと、クォータを無駄に消費し、機能停止が拡大する恐れがあります。
再試行すべきレスポンス
| ステータスコード | 再試行? | メモ |
|---|
408 Request Timeout | あり | リクエストが時間内にサーバーに届きませんでした。同じペイロードで再試行してください。 |
429 Too Many Requests | あり | レート制限が適用されました。retry-afterヘッダーに従います。を参照してください。 |
500 Internal Server Error | あり | 一過性のエラーです。指数バックオフを使用してください。 |
502 Bad Gateway | あり | 一過性のエラーです。指数バックオフを使用してください。 |
503 Service Unavailable | あり | retry-afterヘッダーが存在する場合は、これに従います。問題が解決しない場合は、Boxステータスページを確認してください。 |
4xx (その他) | いいえ | これらはリクエスト自体に問題があることを示しています。リクエストを修正してから再送信してください。 |
ジッターによる指数バックオフの使用
再試行する際は、すでに負荷がかかっているサービスに再試行が集中しないよう、試行間の待機時間を長めにします。シンプルな方法としては、base * 2^attempt秒にわずかなランダム遅延 (ジッター) を加えた時間 (上限あり) だけ待機することで、並列ワーカーによるサンダリングハード現象を防ぎます。
import random, time
def backoff_seconds(attempt: int, base: float = 1.0, cap: float = 60.0) -> float:
delay = min(cap, base * (2 ** attempt))
return delay + random.uniform(0, delay * 0.1)
レスポンスにretry-afterヘッダーが含まれている場合、ユーザーが独自に設定したバックオフ値を使用するのではなく、その秒数以上待ってから再試行します。
適切なリクエストタイムアウトの設定
処理に時間のかかるリクエストはワーカーのリソースを占有し、エラーの発見を妨げます。アプリからBoxへのすべてのHTTP呼び出しに明示的なタイムアウトを設定し、無期限に待機するのではなく、タイムアウトと同時に再試行するようにします。エンドポイントに合わせて適切な値を選択してください。小さなJSONデータを読み取る場合にはタイムアウトを短く設定できますが、アップロードやAI抽出の呼び出しにはさらに長い時間が必要です。Box SDKを使用する場合、自動再試行と指数バックオフの機能が組み込み済みです。
安全な再試行の実施
GETの再試行は常に安全です。POST、PUT、またはDELETEの再試行は、元のリクエストが実際に成功していてもレスポンスが失われていた場合、重複が発生する可能性があります。こうした再試行を安全に行うために、以下の点に注意してください。
- 分割アップロードの場合、既存のアップロードセッションを再利用し、影響を受けた部分のみを再アップロードします。を参照してください。
- 再試行した作成リクエストで
409 item_name_in_useが返された場合、それが処理フローに合致するのであれば、実際の競合ではなく元のリクエストがすでに成功していると見なします。たとえば、POST /files/contentを再試行してitem_name_in_useが返された場合は、親フォルダを表示して、先ほどアップロードしようとしたファイルを探します。ほとんどの場合、レスポンスが失われる前に最初の試行は正常に保存されています。
GET以外のリクエストを再試行する際には、再試行の前にそのリソースがすでに存在していることを確認してください。たとえば、ファイルを再アップロードする前に、宛先フォルダに対してGET /folders/:id/itemsを呼び出し、ファイル名とサイズを比較します。コラボレーションを再作成する前に、GET /folders/:id/collaborationsを呼び出します。
App Diagnosticsツールの使用
ローカルで問題を再現できない場合や、リクエストについてBoxでどのような情報が記録されているかを正確に確認したい場合は、開発者コンソールからを実行します。
このレポートでは、選択した24時間の枠内でアプリケーションが行ったすべてのAPIコールに関する.csvがエクスポートされます。各コールに関する以下の情報が含まれます。
- Boxが返したHTTPステータスコード。
- APIリクエストの継続時間。
API Request ID — これをBoxサポートに送れば、対象のリクエストを確認できます。
- リソース、サブリソース、HTTPメソッド、およびタイムスタンプ。
以下の場合に、App Diagnosticsレポートを使用します。
- リクエストがBoxに届いたかどうかを確認する。
- ユーザー自身のログに記録されなかった、失敗した呼び出しのリクエストIDを特定する。
- 呼び出し量を予想されるパターンと比較する (例: 再試行が急増していないかを確認する)。
- Boxサポートチームに対し、調査に必要な正確な呼び出し情報を提供する。
App Diagnosticsレポートには、過去48時間以内に行われたAPIコールと、承認およびトークン関連のAPIコールは含まれません。リアルタイムの調査を行う場合は、まずアプリケーションログを確認してください。
セットアップの手順については、を参照してください。
Boxサポートに提供するリクエストIDの取得
Boxサポートへのエスカレーションが必要な場合は、Boxのエラーレスポンス全文と、以下のいずれかの情報を1つ以上送ってください。
- エラーレスポンス本文に含まれる
request_idの値。
- 失敗した呼び出しの
box-request-idレスポンスヘッダー。
- App Diagnosticsレポートの
API Request ID列。
このいずれかの情報が得られれば、Boxサポートチームはサーバー側でそのリクエストを正確に特定できます。IDがない場合、1日数百万件にも及ぶAPIコールの中から1件のエラーを調査するためには、はるかに多くの時間を要します。
よくあるシナリオのデバッグ
以下のチェックリストには、ほとんどのアプリで最初に発生するエラー状態が網羅されています。
認証およびトークンの問題
| 症状 | 最初にチェックする項目 |
|---|
401 invalid_token | トークンの有効期限が切れていないか、または無効化されていないかチェックします。トークンを更新するか、新しいトークンをリクエストします。を参照してください。 |
400 invalid_grant、および「Current date time must be before the expiration date time (現在の日時は有効期限の日時よりも前である必要があります)」というメッセージ | アプリを実行しているホストのクロックがNTPと同期されていません。クロックを再同期してください。 |
400 invalid_client | トークンリクエスト内のclient_idとclient_secretの値が、開発者コンソールにおける値と一致していません。 |
400 unauthorized_client | JWTまたはCCGアプリケーションが、企業の管理者によって承認されていません。を参照してください。 |
UI側の承認エラー (管理コンソールのメッセージ) については、を参照してください。
権限およびアクセスの問題
| 症状 | 最初にチェックする項目 |
|---|
403 access_denied_insufficient_permissions | ユーザーまたはサービスアカウントに、その項目へのアクセス権限がないか、必要なスコープがアプリに設定されていません。CCGまたはJWTを使用している場合は、その項目がサービスアカウントと共有されていることを確認してください。 |
403 insufficient_scope | 開発者コンソールのアプリケーションスコープに、このエンドポイントに必要なスコープが含まれていません。を参照してください。 |
ウェブアプリ上で表示されている項目に対する404 not_found | 使用しているトークンが、その項目に招待されていない別のユーザー (多くの場合、サービスアカウント) に属しています。 |
レート制限と容量の問題
| 症状 | 最初にチェックする項目 |
|---|
429 rate_limit_exceeded | retry-afterヘッダーに従い、処理を中断します。を参照して、どの制限に抵触しているかを確認してください。 |
| レイテンシの急上昇と5xxエラー | 既知のインシデントについては、Boxの状態ページをご確認ください。指数バックオフをまだ追加していない場合は、追加します。 |
Webhookの問題
| 症状 | 最初にチェックする項目 |
|---|
| Webhookを受信できない | 対象のURLが外部からHTTPS経由でアクセス可能であり、テスト用のPOSTに対して2xxを返すことを確認します。Webhookが正しいトリガーと項目に関連付けられていることを確認します。 |
| Webhookは受信したが、処理に失敗した | ペイロード全体をログに記録し、それをハンドラーに対して再生します。実稼働環境で処理を実行する前に、署名を検証してください。を参照してください。 |
Boxステータスページの確認
関連性のない複数の呼び出しで5xxエラーが発生し始めた場合、作業中のコードを調べる前に、status.box.comで既知のインシデントが発生していないか確認してください。Boxでインシデントが発生している場合、通常は作業を中断し、既存の再試行ロジックを実行して復帰を待つことをお勧めします。
次の手順
- で、エラーコードの詳細なリストを確認します。
- の設定に合わせて、再試行ポリシーを調整します。
- 次回に予期せぬエラーが発生した際は、を実行してください。