メインコンテンツへスキップ

エラー形式

すべてのエラーは一貫した JSON 形式に従います:
{
  "error": {
    "message": "人間が読めるエラーの説明",
    "type": "error_type"
  }
}

エラータイプ

HTTP ステータスエラータイプ説明
400invalid_request_errorリクエストボディの形式が不正または必須フィールドが欠如
401authentication_errorAPI key が欠如、無効、または期限切れ
402payment_requiredクレジット不足 — アカウントにチャージしてください
403permission_error / forbidden_errorこのキーは要求されたプロバイダーまたはリソースへのアクセス権がない
413invalid_request_errorリクエストボディが大きすぎる(最大 10 MB)
429rate_limit_errorレート制限超過(RPM または日次上限)
502server_errorアップストリームプロバイダーへのリクエストが失敗
503server_error要求されたモデルに利用可能なプロバイダーがない

一般的なエラーと解決策

401 — 無効な API Key

{
  "error": {
    "message": "invalid api key",
    "type": "authentication_error"
  }
}
解決策: API key が正しく、失効していないことを確認してください。

403 — プロバイダーが許可されていない

{
  "error": {
    "message": "provider 'anthropic' is not allowed for this API key",
    "type": "forbidden_error"
  }
}
解決策: お使いの API key には allowed_providers の制限があります。別のキーを使用するか、管理 API で許可されたプロバイダーを更新してください。

429 — レート制限

{
  "error": {
    "message": "rate limit exceeded",
    "type": "rate_limit_error"
  }
}
解決策: 指数バックオフを実装してください。キーのレート制限の引き上げを検討してください。

502 — アップストリームエラー

{
  "error": {
    "message": "upstream request failed",
    "type": "server_error"
  }
}
解決策: LLM プロバイダーがエラーを返したか、アクセスできません。ARouter は自動的にキーのフェイルオーバーを処理しますが、プロバイダー自体に問題が発生している可能性があります。リトライするか、別のプロバイダーに切り替えてください。

コードでのエラー処理

from openai import OpenAI, APIStatusError, APIConnectionError

client = OpenAI(
    base_url="https://api.arouter.ai/v1",
    api_key="lr_live_xxxx",
)

try:
    response = client.chat.completions.create(
        model="openai/gpt-5.4",
        messages=[{"role": "user", "content": "Hello!"}],
    )
except APIStatusError as e:
    if e.status_code == 401:
        print("Invalid API key")
    elif e.status_code == 402:
        print("Insufficient credits — top up your account")
    elif e.status_code == 429:
        print("Rate limited, backing off...")
    elif e.status_code in (502, 503):
        print("Provider error, retrying...")
    else:
        print(f"API error {e.status_code}: {e.message}")
except APIConnectionError:
    print("Network error — check your connection")

リトライ戦略

本番アプリケーションでは以下を推奨します:
  1. 429 と 502 には指数バックオフでリトライ
  2. 400、401、403 はリトライしない — これらは永続的なエラー
  3. 最大リトライ回数を設定(例: 3 回)
  4. マルチモデルルーティングを検討 — あるモデルがリクエストに応えられない場合、modelsroute で順序付きの候補リストを送信
import time
from openai import OpenAI, APIStatusError

def call_with_retry(client, request, max_retries=3):
    for attempt in range(max_retries):
        try:
            return client.chat.completions.create(**request)
        except APIStatusError as e:
            if e.status_code in (429, 502, 503) and attempt < max_retries - 1:
                time.sleep(2 ** attempt)
                continue
            raise

ストリーミング中のエラー処理

ストリーミング(stream: true)を使用する場合、エラーの動作は発生するタイミングによって異なります:
  • Token が送信される前 — ARouter は非 200 ステータスコードを持つ標準 HTTP エラーレスポンスを返します。非ストリーミングエラーと同様に処理します。
  • Token が送信された後 — HTTP ステータスはすでに 200 OK です。エラーはストリームボディ内の SSE イベントとして配信されます。
ストリーム途中のエラーは次のようになります:
{
  "id": "chatcmpl-xxx",
  "object": "chat.completion.chunk",
  "error": {
    "code": "server_error",
    "message": "Provider disconnected unexpectedly"
  },
  "choices": [
    { "index": 0, "delta": { "content": "" }, "finish_reason": "error" }
  ]
}
各チャンクの finish_reason を確認してください。"error" の場合、ストリームが異常終了したことを意味します。
for await (const chunk of stream) {
  // Check for mid-stream error
  if ("error" in chunk) {
    console.error(`Stream error: ${(chunk as any).error.message}`);
    break;
  }
  if (chunk.choices[0]?.finish_reason === "error") {
    console.error("Stream terminated due to an error");
    break;
  }
  const content = chunk.choices[0]?.delta?.content;
  if (content) process.stdout.write(content);
}
完全なストリーミングエラー処理の例については、ストリーミングガイドを参照してください。