# エラー処理

## 統合エラー応答フォーマット

すべての API エラーは、統一された JSON 形式を返します。

```json
{
  "code": 2010,
  "message": "Insufficient credits",
  "suggestion": "Please top up your account at https://platform.tripo3d.ai",
  "request_id": "req_abc123"
}
```

| フィールド | 種類 | 説明 |
| :-: | :-: | :-: |
| code | 整数 | エラーコード |
| message | 文字列 | エラーの説明 |
| suggestion | 文字列 | 提案された修正 |
| request_id | 文字列 | トラブルシューティング用の一意のリクエスト識別子 |

## HTTP ステータス コード

| ステータスコード | 意味 | 説明 |
| :-: | :-: | :-: |
| 200 | 成功 | リクエストは正常に処理されました |
| 400 | 無効なパラメータ | 必須パラメータが欠落しているか形式が不正です |
| 401 | 未認証 | API Key が見つからないか無効です |
| 403 | 権限が不十分です | リソースにアクセスする権限がないか、クレジットが不十分です |
| 404 | リソースが見つかりません | 要求されたタスクまたはリソースは存在しません |
| 429 | リクエストが多すぎます | レート制限を超えました。リクエストの頻度を減らす |
| 500 | サービスエラー | 内部サーバーエラー。後でもう一度試してください |

## エラーコードリファレンス

| エラーコード | 意味 | 推奨取り扱い方法 |
| :-: | :-: | :-: |
| 1000 | 無効なAPI Key | API Keyが正しいか削除されているかを確認してください |
| 1001 | 無許可 | リクエストヘッダーに`Authorization`が含まれているかどうかを確認する |
| 2000 | レート制限を超えました | リクエストの頻度を減らし、指数バックオフを使用した再試行を実装します。 |
| 2002 | サポートされていないリクエストパラメータです | リクエスト本文のフィールド名と値がドキュメントと一致するかどうかを確認する |
| 2003 | 空の入力ファイル | アップロードされたファイルが空ではなく、有効な形式を使用していることを確認します |
| 2004 | サポートされていないファイル形式です | ファイル形式がサポートされているリストにあるかどうかを確認します |
| 2008 | コンテンツポリシー違反 | 入力内容を修正して禁止ワードや禁止画像を避ける |
| 2010 | クレジットが不十分です | コンソールでクレジットを補充する |
| 2015 | 非推奨のバージョン | 最新のAPIバージョンにアップグレードしてください |
| 2018 | モデルが複雑すぎる | 入力モデルの複雑さまたはポリ数を削減します。 |

## エラー処理の例

### Python

```python
import time
import requests

def call_api_with_retry(url, headers, payload=None, max_retries=3):
    for attempt in range(max_retries):
        if payload:
            response = requests.post(url, headers=headers, json=payload)
        else:
            response = requests.get(url, headers=headers)

        if response.status_code == 200:
            return response.json()

        if response.status_code == 429:
            wait = 2 ** attempt
            print(f"Rate limit triggered. Retrying in {wait} seconds...")
            time.sleep(wait)
            continue

        error = response.json()
        raise Exception(
            f"API error [{error['code']}]: {error['message']} "
            f"(suggestion: {error.get('suggestion', 'none')})"
        )

    raise Exception("Maximum retry attempts exhausted")
```

### JavaScript

```javascript
async function callApiWithRetry(url, options, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const response = await fetch(url, options);

    if (response.ok) {
      return await response.json();
    }

    if (response.status === 429) {
      const wait = 2 ** attempt * 1000;
      console.log(`Rate limit triggered. Retrying in ${wait / 1000} seconds...`);
      await new Promise(resolve => setTimeout(resolve, wait));
      continue;
    }

    const error = await response.json();
    throw new Error(
      `API error [${error.code}]: ${error.message} (suggestion: ${error.suggestion || "none"})`
    );
  }

  throw new Error("Maximum retry attempts exhausted");
}
```

## 再試行戦略の推奨事項

429 のレート制限や 500 のサービス エラーなど、再試行可能なエラーの場合は、指数バックオフ戦略を使用します。

1. 最初の再試行: 1 秒待ちます
2. 2 回目の再試行: 2 秒待ちます
3. 3 回目の再試行: 4 秒待ちます
4. 最大再試行回数を 5 回以下に保つ

400、401、403 などの再試行不可能なエラーの場合は、例外を直接スローし、根本的な問題を修正します。
