콘텐츠로 이동

8. 에러 응답과 에러 코드#

8.1 오류 응답 형식#

오류가 발생하면 DataAPI는 다음 형식의 JSON 응답을 반환한다. details 필드는 선택 사항이며, 오류 종류에 따라 포함되지 않을 수 있다.

필드 설명
code DataAPI 오류 코드
message 오류 메시지
path 요청 URL
timestamp 오류 발생 시간
details 추가 오류 정보(선택)

예시:

{
  "code": "DATA_003",
  "message": "SQL 문 실행에 실패했습니다.",
  "path": "/dataapi/query/records",
  "timestamp": "2026-03-03T06:10:31.123Z",
  "details": [
    "SQLSTATE:23505",
    "VENDOR_CODE:-69720",
    "SQLSTATE_TEXT:DB 제약조건 위반이 발생했습니다."
  ]
}

8.2 details 필드#

details 필드는 오류에 대한 추가 정보를 제공하기 위해 사용된다.

상황 대표 코드 details 성격
요청값 검증 실패 COMMON_001 필드별 검증 메시지를 field: message 형태로 포함할 수 있다.
요청 본문 형식 오류 COMMON_002 보통 생략한다.
DB 사용자 인증 실패 AUTH_008 원인이 SQLException 계열이면 안전한 SQL 메타데이터만 포함할 수 있다.
DB 커넥션 대여 실패 DATA_002 원인이 SQLException 계열이면 안전한 SQL 메타데이터만 포함할 수 있다.
SQL 실행 실패 DATA_003 원인이 SQLException 계열이면 안전한 SQL 메타데이터만 포함할 수 있다.
그 외 에러 기타 코드 기본적으로 생략한다.

SQL 오류와 관련된 details 항목은 데이터베이스의 상세 내부 정보가 그대로 노출되는 것을 방지하기 위해 원본 JDBC 에러 메시지를 직접 출력하지 않는다. 대신, 외부 노출에 안전한 다음과 같은 정형 메타데이터 포맷으로만 제공된다.

SQLSTATE:<code>
VENDOR_CODE:<code>
SQLSTATE_TEXT:<safe hint>

8.3 오류 분류표#

오류 분류 대표 코드 HTTP 상태 분류 기준 details
Authorization 헤더 없음 AUTH_001 401 인증 헤더가 필요한 요청에서 헤더가 없거나 logout 요청의 Bearer 형식이 맞지 않음 보통 없음
Refresh 토큰 차단 AUTH_002 401 로그아웃 또는 rotation 이후 블록리스트에 등록된 Refresh 토큰 사용 보통 없음
토큰 유효성 실패 AUTH_003 401 JWT 문자열이 유효하지 않거나 만료되었거나 session reset cutoff 이전에 발급됨 보통 없음
Refresh 토큰 타입 오류 AUTH_004 401 Refresh 전용 토큰이 필요한 경로에 다른 토큰 사용 보통 없음
Access 토큰 타입 오류 AUTH_005 401 Access 전용 토큰이 필요한 경로에 다른 토큰 사용 보통 없음
Access/Refresh 사용자 또는 세션 불일치 AUTH_006 401 logout 등에서 Access 토큰과 Refresh 토큰의 사용자 또는 세션 정보가 다름 보통 없음
세션 풀 만료 또는 부재 AUTH_007 401 서버 인스턴스에 사용자 세션 풀 또는 현재 JWT 세션/refresh rotation 상태가 없음 보통 없음
DB 사용자 인증 실패 AUTH_008 401 DB 사용자명/비밀번호 검증 실패 SQL 메타데이터 가능
인증되지 않은 요청 AUTH_009 401 인증 객체가 없거나 Spring Security 인증 실패가 일반 unauthorized로 매핑됨 보통 없음
Refresh 토큰 재사용 AUTH_010 401 이미 사용되었거나 교체된 Refresh 토큰 사용 보통 없음
지원하지 않는 인증 스킴 AUTH_011 401 Bearer, Basic 외 Authorization 스킴 사용 보통 없음
Basic 자격증명 형식 오류 AUTH_012 401 Basic 헤더 디코딩 또는 username:password 형식 오류 보통 없음
접근 권한 없음 AUTH_013 403 필요한 role이 없는 사용자가 보호 엔드포인트 접근 보통 없음
활성 JWT 세션 충돌 AUTH_014 409 사용자별 활성 JWT 세션 풀이 이미 있어 새 로그인 거부 보통 없음
SQL API 미구현 DATA_001 501 구현되지 않은 SQL 실행 API 호출 보통 없음
DB 커넥션 대여 실패 DATA_002 500 사용자 풀에서 SQL 실행용 DB 커넥션을 대여하지 못함 SQL 메타데이터 가능
SQL 실행 실패 DATA_003 500 SQL 실행 중 DB 오류 또는 실행 오류 발생 SQL 메타데이터 가능
조회 결과 집합 없음 DATA_004 400 조회 엔드포인트에 결과 집합을 반환하지 않는 SQL 요청 보통 없음
실행 엔드포인트 결과 집합 반환 DATA_005 400 /execute에서 결과 집합을 반환하는 SQL 요청 보통 없음
스트리밍 지속 시간 초과 DATA_006 500 스트리밍 응답이 설정된 최대 지속 시간을 초과 stream 시작 전이면 JSON, 시작 후에는 partial NDJSON 가능
buffered LOB inline 제한 초과 DATA_007 400 buffered 조회 응답에서 BLOB/CLOB 값을 inline 제한 안에 담을 수 없음 메시지 placeholder에 타입, 실제 크기, 제한값 포함
execute batch DML 제한 DATA_008 400 /execute batch에 DML이 아닌 SQL 요청 보통 없음
records 중복 컬럼명 DATA_009 400 /query/records 또는 /stream/records 결과에 같은 컬럼 label이 반복됨 메시지 placeholder에 중복 label 포함
요청값 검증 실패 COMMON_001 400 Bean Validation 또는 필드 검증 실패 필드별 검증 메시지 가능
요청 본문 형식 오류 COMMON_002 400 JSON 파싱 또는 요청 본문 변환 실패 보통 없음
서버 내부 오류 COMMON_003 500 별도 코드로 분류되지 않은 내부 런타임 오류 보통 없음

8.4 스트리밍 오류 처리#

스트리밍 엔드포인트는 실시간으로 데이터를 전송하는 특성상, 오류가 발생한 시점에 따라 응답 방식이 달라진다. 클라이언트는 다음 세 가지 경우를 고려하여 구현해야 한다.

응답 전송 시작 전 실패한 경우#

스트림이 전송되기 전에 오류가 발생하면, 표준 JSON 구조의 ErrorResponse를 반환한다.

예시

{"code":"DATA_003","message":"SQL 문 실행에 실패했습니다.","path":"/dataapi/stream/records","timestamp":"..."}

스트림 전송 중 오류 (에러 코드 반환 가능)#

스트림 전송이 시작된 이후, 직전 NDJSON 객체의 전송이 완료된 후 다음 객체를 전송하기 전에 오류가 발생하면 NDJSON형식의 오류 객체를 추가하여 반환할 수 있다. 이 경우 complete 필드가 포함된 객체는 전송되지 않는다.

예시

{"record":{"ID":1,"NAME":"Alice"}}
{"error":true,"code":"DATA_003","message":"SQL 문 실행에 실패했습니다."}

스트림 전송 중 오류(에러 코드 반환 불가)#

스트림 전송이 시작되고 NDJSON 객체를 전송하는 도중 오류가 발생하면, 이미 일부 JSON 데이터가 전송되었을 수 있으므로 오류 객체를 추가하여 반환할 수 없다. HTTP 연결 특성상 중간에 HTTP 상태 코드를 변경하거나 일반 JSON 포맷으로 에러 응답을 보낼 수 없기 때문이다.

이 경우 연결은 불완전한 NDJSON 상태에서 종료되며, complete 필드가 포함된 객체도 전송되지 않는다.

예시:

{"record":{"ID":1,"NAME":"Alice"}}
{"record":{"ID":2,"NAME":

클라이언트 구현 시 주의사항#

스트리밍 응답은 항상 마지막 라인에 complete 필드가 포함된 객체가 전송되어야 정상적으로 종료된 것으로 간주한다. complete 필드가 없으면 '정상 종료'가 아닌 '비정상적인 전송 실패'로 간주하고 예외 처리를 수행해야 한다.