오류 처리

이 가이드는 Caret API가 오류를 보고하는 방법과 애플리케이션에서 이를 처리하는 모범 사례를 설명합니다.

오류 응답 형식

오류가 발생하면 Caret API는 다음을 반환합니다:
  1. 적절한 HTTP 상태 코드
  2. 오류 세부사항이 포함된 JSON 응답 본문
모든 오류 응답은 다음 구조를 가집니다:
{
  "error": {
    "code": "error_code",
    "message": "사람이 읽을 수 있는 오류 메시지",
    "param": "오류를 일으킨 매개변수 (해당되는 경우)",
    "type": "error_type"
  }
}

오류 속성

속성설명
code오류에 대한 문자열 식별자
message사람이 읽을 수 있는 오류 설명
param오류를 일으킨 매개변수 (해당되는 경우)
type발생한 오류의 유형

일반적인 HTTP 상태 코드

상태 코드설명
400잘못된 요청 - 요청에 잘못된 매개변수가 포함됨
401인증되지 않음 - 유효한 API 키가 제공되지 않음
403금지됨 - API 키에 요청을 수행할 권한이 없음
404찾을 수 없음 - 요청한 리소스가 존재하지 않음
409충돌 - 요청이 다른 요청이나 리소스 상태와 충돌함
422처리할 수 없는 엔터티 - 요청은 올바른 형식이지만 의미적 오류가 포함됨
429너무 많은 요청 - 요청 제한 초과
500내부 서버 오류 - Caret 측에서 문제 발생

오류 유형

인증 오류

{
  "error": {
    "code": "invalid_api_key",
    "message": "제공된 API 키가 잘못되었습니다",
    "type": "authentication_error"
  }
}

검증 오류

{
  "error": {
    "code": "invalid_parameter",
    "message": "'title' 매개변수는 문자열이어야 합니다",
    "param": "title",
    "type": "validation_error"
  }
}

요청 제한 오류

{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "요청 제한이 초과되었습니다. 35초 후에 다시 시도해주세요.",
    "retry_after": 35,
    "type": "rate_limit_error"
  }
}

리소스 오류

{
  "error": {
    "code": "resource_not_found",
    "message": "요청한 메모를 찾을 수 없습니다",
    "param": "note_id",
    "type": "resource_error"
  }
}

오류 처리 모범 사례

1. HTTP 상태 코드 확인

응답을 처리하기 전에 항상 응답의 HTTP 상태 코드를 확인하세요. 다른 상태 코드는 다른 처리 전략이 필요할 수 있는 다른 유형의 오류를 나타냅니다.

2. 오류 객체 파싱

디버깅에 도움이 되도록 응답 본문에서 상세한 오류 정보를 추출하고 로깅하세요.

3. 요청 제한을 적절히 처리

429 Too Many Requests 오류를 받으면 retry_after 값을 사용하여 언제 요청을 재시도할지 결정하세요.

4. 지수 백오프 구현

일시적인 오류(예: 500 오류)의 경우, 증가하는 간격으로 요청을 재시도하는 지수 백오프 전략을 구현하세요.

5. 사용자 친화적인 메시지 표시

원시 API 오류 메시지를 최종 사용자에게 노출하지 마세요. 대신 애플리케이션 UI에 더 사용자 친화적인 메시지로 번역하세요.

코드 예제

JavaScript

async function makeApiRequest(url, options) {
  try {
    const response = await fetch(url, options);

    if (!response.ok) {
      const errorData = await response.json();

      // 특정 오류 유형 처리
      switch (response.status) {
        case 401:
          // 인증 오류 처리
          console.error('인증 실패:', errorData.error.message);
          // 로그인으로 리디렉션 또는 토큰 갱신
          break;

        case 404:
          // 찾을 수 없음 오류 처리
          console.error('리소스를 찾을 수 없음:', errorData.error.message);
          break;

        case 429:
          // 요청 제한 오류 처리
          const retryAfter = errorData.error.retry_after || 60;
          console.error(`요청 제한됨. ${retryAfter}초 후 재시도`);
          // 재시도 로직 구현
          break;

        default:
          // 기타 오류 처리
          console.error('API 오류:', errorData.error.message);
      }

      throw new Error(errorData.error.message);
    }

    return await response.json();
  } catch (error) {
    // 네트워크 오류 처리
    console.error('요청 실패:', error.message);
    throw error;
  }
}

Python

import requests
import time

def make_api_request(url, options, max_retries=3):
    retries = 0

    while retries < max_retries:
        try:
            response = requests.request(options.get('method', 'GET'), url, **options)

            if response.ok:
                return response.json()

            error_data = response.json()
            error = error_data.get('error', {})

            # 특정 오류 유형 처리
            if response.status_code == 429:
                retry_after = error.get('retry_after', 2 ** retries)
                print(f"요청 제한됨. {retry_after}초 후 재시도...")
                time.sleep(retry_after)
                retries += 1
                continue

            if response.status_code >= 500:
                # 서버 오류, 백오프로 재시도
                backoff_time = 2 ** retries
                print(f"서버 오류. {backoff_time}초 후 재시도...")
                time.sleep(backoff_time)
                retries += 1
                continue

            # 클라이언트 오류, 재시도하지 않음
            print(f"API 오류: {error.get('message')}")
            raise Exception(error.get('message'))

        except requests.exceptions.RequestException as e:
            # 네트워크 오류, 백오프로 재시도
            if retries == max_retries - 1:
                raise e

            backoff_time = 2 ** retries
            print(f"요청 실패: {str(e)}. {backoff_time}초 후 재시도...")
            time.sleep(backoff_time)
            retries += 1

    raise Exception("최대 재시도 횟수 도달")

다음 단계