에러 처리
D.Hub API에서 오류가 발생하면 적절한 HTTP 상태 코드와 함께 JSON 형식의 에러 메시지가 반환됩니다. 이 페이지에서는 에러 응답 구조, 상태 코드별 의미, 자주 발생하는 에러의 해결 방법을 설명합니다.
에러 응답 구조
모든 에러 응답은 다음과 같은 JSON 구조를 가집니다.
{
"detail": "에러에 대한 설명 메시지"
}
detail 필드에는 에러의 원인을 설명하는 문자열이 포함됩니다. 일부 유효성 검증 에러(422)는 상세한 필드별 정보를 포함할 수 있습니다.
{
"detail": [
{
"loc": ["body", "name"],
"msg": "field required",
"type": "value_error.missing"
}
]
}
HTTP 상태 코드
성공 응답
| 상태 코드 | 의미 | 설명 |
|---|---|---|
200 OK | 성공 | 요청이 정상적으로 처리됨 |
201 Created | 생성 완료 | 새 리소스가 성공적으로 생성됨 |
204 No Content | 삭제 완료 | 리소스가 성공적으로 삭제됨 (응답 본문 없음) |
클라이언트 에러
| 상태 코드 | 의미 | 설명 |
|---|---|---|
400 Bad Request | 잘못된 요청 | 요청 본문이 잘못되었거나 필수 파라미터 누락 |
401 Unauthorized | 인증 실패 | 토큰이 없거나, 만료되었거나, 유효하지 않음 |
403 Forbidden | 권한 없음 | 인증은 되었으나 해당 리소스에 대한 접근 권한이 없음 |
404 Not Found | 리소스 없음 | 요청한 리소스가 존재하지 않음 |
409 Conflict | 충돌 | 리소스가 이미 존재하거나 상태 충돌 |
422 Unprocessable Entity | 유효성 검증 실패 | 요청 데이터의 형식이나 값이 유효하지 않음 |
서버 에러
| 상태 코드 | 의미 | 설명 |
|---|---|---|
500 Internal Server Error | 서버 내부 오류 | 서버에서 예기치 않은 오류 발생 |
공통 에러 시나리오와 해결 방법
| 에러 메시지 | 상태 코드 | 원인 | 해결 방법 |
|---|---|---|---|
Not authenticated | 401 | Authorization 헤더 누락 | Authorization: Bearer {token} 헤더 추가 |
Token has expired | 401 | access_token 만료 | refresh_token으로 토큰 갱신 또는 재로그인 |
Invalid token | 401 | 토큰 형식이 잘못됨 | 토큰 문자열이 정확한지 확인 |
Forbidden | 403 | 리소스 접근 권한 없음 | 관리자에게 권한 요청 |
Dataset not found | 404 | 존재하지 않는 데이터셋 ID | ID 값 확인 또는 목록 API로 유효한 ID 조회 |
Collection not found | 404 | 존재하지 않는 컬렉션 ID | ID 값 확인 또는 목록 API로 유효한 ID 조회 |
Name already exists | 409 | 동일한 이름의 리소스 존재 | 다른 이름을 사용하거나 기존 리소스 삭제 후 재시도 |
field required | 422 | 필수 필드 누락 | 요청 본문에 필수 필드 포함 여부 확인 |
value is not a valid integer | 422 | 필드 타입 불일치 | API 문서에서 올바른 데이터 타입 확인 |
File too large | 400 | 업로드 파일 크기 초과 | 파일 크기를 줄이거나 분할 업로드 |
Pipeline is already running | 409 | 파이프라인 중복 실행 | 현재 실행이 완료될 때까지 대기 |
Internal server error | 500 | 서버 내부 오류 | 잠시 후 재시도, 지속 시 관리자에게 문의 |
에러 처리 모범 사례
Python
import requests
response = requests.get(
"https://{host}/api/v1/datasets/{dataset_id}",
headers={"Authorization": f"Bearer {token}"},
)
if response.status_code == 200:
data = response.json()
elif response.status_code == 401:
# 토큰 갱신 후 재시도
token = refresh_access_token()
response = requests.get(
"https://{host}/api/v1/datasets/{dataset_id}",
headers={"Authorization": f"Bearer {token}"},
)
elif response.status_code == 404:
print("데이터셋을 찾을 수 없습니다.")
else:
error = response.json()
print(f"에러 발생: {error['detail']}")
cURL
response=$(curl -s -w "\n%{http_code}" \
-H "Authorization: Bearer ${TOKEN}" \
"https://{host}/api/v1/datasets/${DATASET_ID}")
http_code=$(echo "$response" | tail -1)
body=$(echo "$response" | head -1)
if [ "$http_code" -ne 200 ]; then
echo "에러 ($http_code): $body"
fi
재시도 전략
일시적 오류 처리
네트워크 문제나 서버 부하로 인한 일시적 오류(5xx)는 재시도로 해결될 수 있습니다. 다음 전략을 권장합니다.
- 재시도 대상:
500,502,503,504상태 코드 - 재시도 횟수: 최대 3회
- 대기 간격: 지수 백오프 (1초 → 2초 → 4초)
- 재시도 금지:
400,401,403,404,409,422는 요청 자체를 수정해야 하므로 재시도하지 마세요.
import time
import requests
def api_request_with_retry(url, headers, max_retries=3):
for attempt in range(max_retries):
response = requests.get(url, headers=headers)
if response.status_code < 500:
return response
wait = 2 ** attempt
time.sleep(wait)
return response