에러 핸들링

1. 들어가며

 

DB에서는 다양한 에러가 발생합니다. 이런 에러에 대해 500 에러로 처리할 수 있지만 retry를 하거나 다른 핸들링 로직을 추가하고 싶을 수 있습니다. 하지만 MySQL 에러는 다양한 구분과 다양한 코드를 가지고 있습니다. 이러한 에러를 어떻게 해야 범용성 있게, 우아하게 핸들링 할 수 있는지 알아보도록 하겠습니다.

 

2. 에러 핸들링

구분

MySQL 에러 구분:

  • Global Error
    • Server-side & Client-side에서 공용으로 발생
  • Server Error
    • Server-side에서만 발생
  • Client Error
    • Client-side에서만 발생

주의사항

  • 일부 에러는 서버에서만 찾으면 되고, 아니면 client에서만 찾는 등 에러 번호 만으로 디버깅 위치를 특정할 수 있습니다다.
  • 다만 일부 Server-Error는 Client side로 전달되기 때문에 client로 전달되었다고 client error라고 단정하면 안 됩니다.
  • 예를 들어 아래 에러는 서버 에러 대역이지만 client로 전송됩니다.. 에러 발생 주체는 서버라는 것입니다.
ERROR 1602 (23000): Duplicate entry 'abc...' for key 'ux_email'

포맷

MySQL의 에러는 3개의 파트로 구성되어 있습니다.

  • Error No
  • SQL  State
  • Error Message

각각의 파트를 살펴보고 핸들링에 도움되는 정보가 무엇인지 알아보도록 하겠습니다.

 

1) Error No

  • 4자리 정수
  • MySQL에서만 유효한 정보
  • 에러 번호의 구분
    • 1 ~ 999: Global Error
    • 1000 ~ 1999: MySQL Server Error
    • 2000 ~ 2999: MySQL Client Error
    • 이후: MySQL Server Error

3500 이후 대역은 MySQL 8.0 이후 추가된 대역입니다.

즉 대역 별로 에러 범위를 찾을 수 있습니다.

 

2) SQL STATE

  • 5글자 영문 숫자로 구성
  • ANTI-SQL 에서 제정한 Vendor 비 의존적 에러 코드
  • SQL-STATE는 두 파트로 구분
    • 앞 두글자: 상태값의 구분
      • 00: 정상
      • 01: 경고
      • 02: 레코드 없음
      • HY: ANSI-SQL에서 아직 표준 분류를 하지 않은 상태 (벤더 의존적)
      • 나머지는 모두 에러
    • 뒷 세 글자: 주로 숫자값이며 각 분류별 상세 에러 코드 값.

SQL STATE는 꼭 에러가 아닌 정보성도 포함되어 있음을 알 수 있습니다.

 

3) Error Message

 

  • 사람이 인식할 수 있는 문자열입니다.
  • 이건 버전 간 호환이 유지되지 않는 경우가 많습니다.
  • release note에 명시되지 않는 편입니다. 즉 에러 핸들링을 위해서 사용하기엔 별로입니다.

따라서 Error Message의 경우 동일한 에러여도 MySQL 버전 별로 다른 메시지가 나올 수 있기 때문에, 해당 메시지로 에러 핸들링을 해서는 안 됩니다.

심지어 마이너 버전에도 다를 수 있습니다. 무엇보다 해당 변경이 릴리즈 노트에도 적히지 않습니다.

 

에러 핸들링 기준

  • Error Message는 자주 바뀌며 변경이 명시되지 않기에 적합하지 않습니다.
  • Error No의 경우 스토리지 엔진마다도 Error No가 다르기 때문에 적합하지 않습니다.
  • SQL STATE의 경우 스토리지 엔진 간 호환성을 제공하고 다른 Vendor DBMS와의 호환성도 제공합니다.

따라서 SQL STATE가 적합함을 알 수 있습니다.

 

하지만 SQL-STATE가 HY로 시작하는 경우…

  • 버전 별로 다를 수 있습니다.
  • 따라서 HY로 시작할 경우 Error No를 이용해서 에러 처리 하는 것을 권장합니다.