> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tokenlab.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# 오류 처리

> API 오류를 우아하게 처리하기

## 오류 응답 형식

모든 오류는 선택적인 [Agent-First 힌트](/guides/agent-first-api)와 함께 일관된 JSON 형식으로 반환됩니다:

```json theme={null}
{
  "error": {
    "message": "Human-readable error description",
    "type": "error_type",
    "code": "error_code",
    "param": "parameter_name",
    "did_you_mean": "suggested_model",
    "suggestions": [{"id": "model-id"}],
    "hint": "Next step guidance",
    "retryable": true,
    "retry_after": 30
  }
}
```

필수 기본 필드인 `message`와 `type`은 항상 존재합니다. `code`와 `param`은 선택 사항이며 관련이 있을 때만 반환됩니다. 힌트 필드 (`did_you_mean`, `suggestions`, `hint`, `retryable`, `retry_after`, `balance_usd`, `estimated_cost_usd`)는 AI 에이전트의 자체 수정(self-correction)을 위한 선택적 확장입니다. 자세한 내용은 [Agent-First API 가이드](/guides/agent-first-api)를 참조하세요.

OpenAI 호환 endpoints는 TokenLab의 안정적인 게이트웨이 오류 유형을 사용합니다. Anthropic-compatible 및 Gemini-compatible endpoints는 자체 네이티브 오류 계열 및 응답 형태를 사용합니다.

## HTTP 상태 코드

| 코드  | 설명                           |
| --- | ---------------------------- |
| 400 | 잘못된 요청 - 잘못된 파라미터            |
| 401 | 인증 실패 - 유효하지 않거나 누락된 API 키   |
| 402 | 결제 필요 - 잔액 부족                |
| 403 | 접근 금지 - 접근 거부 또는 모델 사용 불가    |
| 404 | 찾을 수 없음 - 모델 또는 리소스가 없음      |
| 413 | 요청 본문이 너무 큼 - 입력 또는 파일 크기 초과 |
| 429 | 요청 과다 - 속도 제한 초과             |
| 500 | 서버 내부 오류                     |
| 502 | 잘못된 게이트웨이 - 업스트림 제공자 오류      |
| 503 | 서비스 사용 불가 - 서비스 일시적 사용 불가    |
| 504 | 게이트웨이 타임아웃 - 요청 시간 초과        |

## 오류 유형

### 인증 오류 (401)

| 유형                | 코드                | 설명                    |
| ----------------- | ----------------- | --------------------- |
| `invalid_api_key` | `invalid_api_key` | API 키가 누락되었거나 유효하지 않음 |
| `expired_api_key` | `expired_api_key` | API 키가 폐기되었음          |

```python theme={null}
from openai import OpenAI, AuthenticationError

try:
    response = client.chat.completions.create(...)
except AuthenticationError as e:
    print(f"Authentication failed: {e.message}")
```

### 결제 오류 (402)

| 유형                     | 코드                     | 설명             |
| ---------------------- | ---------------------- | -------------- |
| `insufficient_balance` | `insufficient_balance` | 계정 잔액이 부족함     |
| `quota_exceeded`       | `quota_exceeded`       | API 키 사용 한도 초과 |

```python theme={null}
from openai import OpenAI, APIStatusError

try:
    response = client.chat.completions.create(...)
except APIStatusError as e:
    if e.status_code == 402:
        print("Please top up your account balance")
```

### 접근 오류 (403)

| 유형              | 코드                  | 설명                       |
| --------------- | ------------------- | ------------------------ |
| `access_denied` | `access_denied`     | 리소스 접근 거부                |
| `access_denied` | `model_not_allowed` | 이 API 키로 해당 모델을 사용할 수 없음 |

```json theme={null}
{
  "error": {
    "message": "You don't have permission to access this model",
    "type": "access_denied",
    "code": "model_not_allowed"
  }
}
```

### 유효성 검사 오류 (400)

| 유형                        | 설명                         |
| ------------------------- | -------------------------- |
| `invalid_request_error`   | 요청 파라미터가 유효하지 않음           |
| `context_length_exceeded` | 모델에 대한 입력 길이가 너무 김         |
| `model_not_found`         | 요청한 모델이 현재 모델 세부정보에서 사용 불가 |

```json theme={null}
{
  "error": {
    "message": "Model not found: please check the model name",
    "type": "invalid_request_error",
    "param": "model",
    "code": "model_not_found",
    "did_you_mean": "gpt-5.4",
    "suggestions": [{"id": "gpt-5.4"}, {"id": "gpt-5-mini"}],
    "hint": "Did you mean 'gpt-5.4'? Use GET https://api.tokenlab.sh/v1/models to list all available models."
  }
}
```

공개 라우트는 응답 본문에서 오타, 비공개(hidden), 보류(deferred), 비공개 상태를 구분하지 않습니다. 모델이 현재 모델 세부정보을 통해 사용 불가능한 경우, TokenLab는 `model_not_found`를 반환합니다.

### 속도 제한 오류 (429)

요금 제한을 초과하면:

```json theme={null}
{
  "error": {
    "message": "Rate limit: 1000 rpm exceeded",
    "type": "rate_limit_exceeded",
    "code": "rate_limit_exceeded",
    "retryable": true,
    "retry_after": 8,
    "hint": "Rate limited. Retry after 8s. Current limit: 1000/min for user role."
  }
}
```

**포함된 헤더:**

```
Retry-After: 8
```

`Retry-After` 헤더와 `retry_after` 필드는 모두 재시도 전 대기해야 할 정확한 초(seconds)를 나타냅니다.

### 페이로드가 너무 큼 (413)

입력 또는 파일 크기가 제한을 초과하면:

```json theme={null}
{
  "error": {
    "message": "Input size exceeds maximum allowed",
    "type": "invalid_request_error",
    "code": "payload_too_large"
  }
}
```

일반적인 원인:

* 이미지 파일이 너무 큼 (최대 20MB)
* 오디오 파일이 너무 큼 (최대 25MB)
* 입력 텍스트가 모델의 컨텍스트 길이를 초과함

### 업스트림 오류 (502, 503)

| 유형                    | 설명             |
| --------------------- | -------------- |
| `upstream_error`      | 제공자가 오류를 반환함   |
| `all_channels_failed` | 사용 가능한 제공자가 없음 |
| `timeout_error`       | 요청이 시간 초과됨     |

모든 채널이 실패하면 응답에 대체 모델이 포함됩니다:

```json theme={null}
{
  "error": {
    "message": "Model claude-opus-4-6 temporarily unavailable",
    "code": "all_channels_failed",
    "retryable": true,
    "retry_after": 30,
    "alternatives": [
      {"id": "claude-sonnet-4-6", "status": "available", "tags": []},
      {"id": "gpt-5-mini", "status": "available", "tags": []}
    ],
    "hint": "Retry in 30s or switch to an available model."
  }
}
```

## Python에서 오류 처리

```python theme={null}
from openai import OpenAI, APIError, RateLimitError, APIConnectionError

client = OpenAI(
    api_key="sk-your-api-key",
    base_url="https://api.tokenlab.sh/v1"
)

def chat_with_retry(messages, max_retries=3):
    for attempt in range(max_retries):
        try:
            return client.chat.completions.create(
                model="gpt-4o",
                messages=messages
            )
        except RateLimitError as e:
            if attempt < max_retries - 1:
                import time
                time.sleep(2 ** attempt)  # Exponential backoff
                continue
            raise
        except APIConnectionError as e:
            print(f"Connection error: {e}")
            raise
        except APIError as e:
            print(f"API error: {e.status_code} - {e.message}")
            raise
```

## JavaScript에서 오류 처리

```javascript theme={null}
import OpenAI from 'openai';

const client = new OpenAI({
  apiKey: 'sk-your-api-key',
  baseURL: 'https://api.tokenlab.sh/v1'
});

async function chatWithRetry(messages, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await client.chat.completions.create({
        model: 'gpt-4o',
        messages
      });
    } catch (error) {
      if (error instanceof OpenAI.RateLimitError) {
        if (attempt < maxRetries - 1) {
          await new Promise(r => setTimeout(r, 2 ** attempt * 1000));
          continue;
        }
      }
      throw error;
    }
  }
}
```

## 모범 사례

<AccordionGroup>
  <Accordion title="지수적 백오프 구현">
    속도 제한에 걸렸을 때 재시도 사이에 점점 더 긴 대기 시간을 둡니다:

    ```python theme={null}
    wait_time = 2 ** attempt  # 1s, 2s, 4s, 8s...
    ```
  </Accordion>

  <Accordion title="타임아웃 설정">
    요청이 중단되는 것을 방지하려면 항상 적절한 타임아웃을 설정하세요:

    ```python theme={null}
    client = OpenAI(timeout=60.0)  # 60 second timeout
    ```
  </Accordion>

  <Accordion title="디버깅을 위한 오류 로깅">
    지원 요청을 위해 요청 ID를 포함한 전체 오류 응답을 로깅하세요:

    ```python theme={null}
    except APIError as e:
        logger.error(f"API Error: {e.status_code} - {e.message}")
    ```
  </Accordion>

  <Accordion title="모델별 오류 처리">
    일부 모델은 특정 요구사항(예: 최대 토큰 수, 이미지 형식)을 가집니다.
    요청을 하기 전에 입력을 검증하세요.
  </Accordion>
</AccordionGroup>
