메인 콘텐츠로 건너뛰기

오류 형식

모든 오류는 일관된 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);
}
완전한 스트리밍 오류 처리 예제는 스트리밍 가이드를 참조하세요.