좋은 에러 메시지 쓰는 법

원문

에러 메시지를 2가지로 분류한다

우선, 에러 메세지라고 해도 다음의 2가지 패턴에서 크게 달라진다.
(1) 이용자가 보는 에러 메세지
(2) 개발자가 보는 에러 메시지

(1) 이용자가 보는 에러 메세지

내부 구현에 대해서는 적지 않는다
| | | |–|–| |NG | MySQL의 쿼리 실행에 실패했습니다 ‘SELECT*FROM …’ | |OK | 검색 처리에서 에러가 발생했습니다 |

소스 코드의 “어딘가 ~” 나 “어떤 라이브러리에서 ~” 와 같은 프로그래머만 아는 정보는 쓰지 않도록 한다.
사용자 측에서 보면 수수께끼의 영어의 나열 되어서 무섭고, 악의가 있는 사용자에게 부정 행위를 위한 힌트를 줄 가능성이 있는 위험이다
가령 위의 “나쁜 사례”에서는 MySQL을 사용하는 것과 어떤 SQL문을 실행하고 있는가, 테이블 이름은… 라는 정보가 보여서 공격의 힌트를 줄지 모른다.
물론 개발자만 보는 오류 메시지의 경우 거꾸로 된다.

사용자 입력이 원인인 경우 분명히 사유를 적는다

   
NG 입력 란이 부정입니다
OK 유저 ID는 4글자 이상의 숫자로 입력하세요

사용자 입력 내용이 원인인 경우 “뭐가 잘못된 것인지?” 구체적으로 내놓지 않으면 사용자는 짜증 난다.

(2) 개발자가 보는 에러 메시지

개발자용 에러 메시지는 사용자용과는 달리 오류가 발생한 곳을 가급적 빠르게 파악하기 때문에 자세히 구체적으로 한다.

에러에 관련된 값을 구체적으로 내놓는다

   
NG config file not found
OK config file not found:/path/to/config.ini

가령”설정 파일이 발견되지 않았습니다”라고 말해도 “어디의 설정 파일을 열다가 에러가 났어?”라고 혼란스럽다.
또 기대한 값과 실제 값이 다른 경우는 “xx를 기대했지만 실제는 yy로 에러가 되었다” 라고 하는 부분까지 구체적으로 내놓는 것이 알기 쉽다.

원인을 특정하기 쉽도록 하는 글을 넣는다

   
NG table”users”not found
OK table”users”not found.have you init db?

일어난 것을 전하는 것은 중요하지만 더 중요한 것은 “원인은 xx이지 않을까?”, “~을 잊지 않았습니까?” 라고 제안을 해 주면 “아 ~ 그렇구나!”라고 알기 쉬워진다.

올바른 문법이 아니라도 영어를 사용

가능하면 에러 메시지는 영어로 쓰도록 하자.
그 이유는 다음과 같다.

  • 문자 인코딩 관련 문제에 부닥칠 가능성이 있다
  • vim에서 영어/한글 입력 전환이 피곤

여기에서는 문법은 신경 쓰지 말고 쓰자.
올바른 문법보다는 무슨 일이 일어나는지 알면 충분하다.

가령 user(id=1) register fail 라는 오류 메시지는 (아마도)문법적으로는 이상하지만 “사용자(ID:1), 등록 실패”란 단어에서 무엇이 일어났는지 찾기 쉽다.

에러에 이르기까지의 이력(스택 추적 등)을 표시한다

개발자로서는 에러가 발생했을 때 “어떤 경위로 에러가 났는지”가 알려지면 매우 유용하다.
대개 프로그램 실행 환경에서는 스택 추적을 표시하는 처리가 준비되어 있으므로 개발자용 에러 메시지에 달아 두면 좋을 것이다.

복수인 것은 자신을 식별하는 값을 함께 표시한다

   
NG user register fail
OK [ID:12345]user register fail

등록 유저나, 멀티 스레드 등 복수 존재하는 것을 다루는 경우 “에러가 발생한 것은 복수인 것 중 어느 개체인가”를 아는 것으로 찾기 쉬워진다.
유저 ID와 스레드 ID, IP 주소 등의 개체를 특정할 수 있는 것은 가급적 함께 넣자.

발생 시각을 자세히 표시

에러 메시지가 많이 나오고 있는 상황의 경우 “언제 발생한 장애인지”는 중요한 정보가 된다.
특히 장시간 실행하는 서버 등에서는 로그에 복수의 에러 메시지가 느는 것도 자주 있으므로 초 보다 작은 단위까지 확실히 시간을 표시해 두면 좋다.


이 글은 2019-05-05에 작성되었습니다.