開発環境では問題なく動く。次に書くのは、本番で実際に効いてくる部分――catch ブロックです。サードパーティ API の HTTP エラーは、それだけでは実態が見えません。赤いステータスコードが出るだけで、午前 3 時に本当に知りたい問い――原因はリクエストか、キーか、プランか、それとも相手側のサーバーか――には答えてくれない。そのうえ、どれをリトライし、どれをユーザーに見せるべきかも分かりにくいものです。
Lingo.dev は、その曖昧さを構造で解消します。エラーは、同期・非同期を問わず、どのエンドポイントでも同じ JSON オブジェクトで返り、ステータスコードも 1 つの固定テーブルから選ばれます。ステータスコードは単なるラベルではありません。次に何をすべきかを示す指示です。リクエストを直すべきか、キーをローテーションすべきか、アカウントにチャージすべきか、いったん待つべきか、それともリトライすべきかが分かります。コードを見れば、次の一手が分かる。 ステータスコードを軸にした 1 つのエラーハンドラーで、API 全体をカバーできます。
このページの内容
エラーの形式#
2xx 以外のレスポンスは、すべて同じボディです。何が起きたかを説明する message フィールドを 1 つだけ持つ JSON オブジェクトが返ります。
{
"message": "Invalid API key"
}これが契約のすべてです。展開すべきラッパーはなく、エンドポイントごとに例外扱いするエラー形式もありません。/process/localize の 400 でも、ジョブ参照の 404 でも、返ってくる形は同じです。違うのはステータスコードと message のテキストだけです。
メッセージ本文ではなくステータスコードで判定する
安定したシグナルは HTTP ステータスコードです。エラーハンドリングはそこを基準に分岐してください。message 文字列はログを読む人のための説明であり、機械可読なエラーコードではありません。文言そのものに依存したパターンマッチは避けてください。
ステータスコード#
すべてのレスポンスは 7 つのステータスコードでカバーされます。ここでは 誰が解決するか ごとに整理しています。これはそのまま、リトライ方針でもあります。
リクエスト側に原因がある場合(リクエストを修正し、むやみにリトライしない):
| ステータス | 意味 |
|---|---|
400 Bad Request | リクエストのバリデーションに失敗しました。必須フィールドの不足、無効なロケール、HTTP(HTTPS ではない)の callbackUrl、不正なペイロードなどが該当します。 |
401 Unauthorized | X-API-Key ヘッダーがないか、値が無効です。Authentication を参照してください。 |
403 Forbidden | キー自体は有効ですが、要求されたリソースへのアクセス権がありません。 |
404 Not Found | 指定されたリソース――エンジン、ジョブ、ジョブグループ――は存在しません。 |
組織がアカウント上限に達している場合(請求まわりで解決):
| ステータス | 意味 |
|---|---|
402 Payment Required | 組織がクレジット上限に達しています。 |
429 Too Many Requests | 組織が 1 日あたりのトークンクォータに達しています。上限を引き上げるにはプランをアップグレードしてください。 |
Lingo.dev 側で何かが失敗した場合(一時的な問題なのでリトライ):
| ステータス | 意味 |
|---|---|
500 Internal Server Error | 予期しない障害です。データベースエラー、またはエンジンで設定されたすべてのモデルへの翻訳リクエストが失敗したケースなどが含まれます。 |
401 と 403 は似て見えても、同じ問題ではありません。401 は呼び出し元をまったく識別できなかったことを意味し、403 はキーは識別できたもののアクセスが許可されていないことを意味します。401 で見直すべきなのはキー自体です(ローテーションするか確認する)。一方、403 で見直すべきなのはキーに付与されたアクセス権です。
どのエラーをリトライすべきか#
どんなエラー一覧でも、慎重なインテグレーターが最初に知りたいのはたいてい同じです。しかも、その答えが書かれていないことが多い。どれをリトライすべきか、です。答えは上のグルーピングにあります。
- 4xx – むやみにリトライしない。
400、401、403、404は、あなたの リクエスト側にある条件を示しています。同じリクエストをそのまま送り直しても、同じエラーが再現されるだけです。入力、キー、またはリソース ID を修正してから再送してください。 - 402 と 429 – いったん待機し、その後で上限を解消する。 これらはリクエスト単位では一時的なものではありません。根本にある上限が変わらない限り、次のリクエストも同じ壁にぶつかります。短いループでリトライするのはやめ、上限到達を明示し、解消してください(チャージする、またはプランをアップグレードする)。
- 500 – バックオフ付きでリトライする。 本当に一時的なのはこのクラスだけです。
500は、その呼び出しで設定済みのすべてのモデルがタイムアウトしたことを意味する場合があります。リトライすれば健全なモデルに当たるかもしれません。指数バックオフとリトライ回数の上限を使ってください。
非同期 API は結果の返し方が異なる
このリトライ方針は、自分で投げる 同期 呼び出し向けです。async localization API は、処理結果に対するステータスコードを返しません。POST は、リクエストが受理されると 202 を返し、各ターゲットロケールは耐久性のあるバックグラウンドワークフロー上で独立したジョブとして実行されます。元の呼び出しでステータスコードを捕まえるのではなく、ジョブをポーリングするか、結果を webhook で受け取ります。詳しくは 非同期ジョブのエラーはどこにあるか を参照してください。
402 と 429: 2 つの異なる上限#
この 2 つのアカウントレベルのコードは似て見えます。どちらも「使い切った」ように読めるため、混同すると開発者を誤った対処に向かわせてしまいます。実際には、別々の上限であり、解決方法もそれぞれ異なります。
402 Payment Required– 組織が クレジット上限 に達しています。これは請求上の制約です。組織の請求状態が変わるまで、次の呼び出しも失敗し続けます。429 Too Many Requests– 組織が 1 日あたりのトークンクォータ に達しています。これはリセットされる使用量上限で、引き上げるにはプランのアップグレードが必要です。
ハンドラー内で両者を分けて扱うべき理由はここにあります。402 は人が行う請求アクションですが、429 は待ってリセットを待つか、アップグレードで引き上げるクォータです。両方を単なる「支払いの問題」という汎用メッセージにまとめてしまうと、運用担当者が実際に引くべきレバーが見えなくなります。
402 のボディは、ほかのエラーと見た目が変わりません。クレジット上限だと分かるのはステータスコードです。
{
"message": "Organization has reached its credit limit"
}非同期ジョブのエラーはどこにあるか#
ここは、はっきり線を引いておく価値があります。ステータスコードハンドラーが適切なツールでなくなる境目だからです。
このページのステータスコードは トランスポートレベル のものです。つまり、API があなたの HTTP リクエストを受け付け、処理できたかどうかを示しています。非同期 API からの 202 は、リクエストが受理されたことを意味します。翻訳が成功したことを意味するわけではありません。非同期ジョブは問題なく受理されても、実行途中でモデルがタイムアウトし、あとから失敗することがあります。その失敗は元の呼び出しに対する HTTP ステータスコードとしては返らず、ジョブ自体に記録されます。
つまり、非同期の失敗が現れる場所は 3 つあり、どれもこの表には載っていません。
- ジョブごとのステータス。 失敗したロケールには、ジョブ上に
status: "failed"とerrorMessageが記録されます。job statuses を参照してください。 - グループステータス。 一部のロケールが成功し、ほかが失敗した場合、グループは
partialを返します。成功したロケールはそのまま出荷されます。tracking a job group を参照してください。 - Webhook 配信。 失敗は
translation.failedイベントとして配信され、errorフィールドが含まれます。webhook delivery を参照してください。
もう 1 つ、見落とされやすい違いがあります。重要ではない pipeline ステージの失敗は、ジョブ自体の失敗にはなりません。ジョブはエラーではなく、completed_with_warnings とステップごとの警告を伴って完了します。これはエラーコードの問題ではなく、パイプラインの可観測性に関する話です。observe pipeline runs を参照してください。
次のステップ#
クリーンなエラーハンドラーを作るなら、まずは統合時に最初に遭遇しやすい 2 つ――認証まわりと、非同期処理が独自に結果を返すポイント――から押さえるのがおすすめです。
