문제 정의
API 에러 처리는 백엔드 내부 구현처럼 보이지만 사용자는 에러 메시지로 제품의 신뢰도를 판단합니다. 같은 장애라도 “요청에 실패했습니다”만 보이면 사용자는 다시 시도해야 하는지, 기다려야 하는지, 입력을 고쳐야 하는지 알 수 없습니다.
작은 서비스일수록 에러 처리를 늦게 다루기 쉽습니다. 하지만 오류가 드러나는 방식은 가입, 결제, 글 작성, 구독처럼 전환이 일어나는 순간에 바로 영향을 줍니다.
상황과 배경
프론트엔드가 모든 실패를 하나의 toast로 처리하면 빠르게 구현할 수는 있습니다. 문제는 장애, 권한 부족, 유효성 오류, 중복 요청, 네트워크 단절이 모두 같은 경험으로 보인다는 점입니다. 운영자는 로그에서 원인을 찾기 어렵고, 사용자는 자신의 행동을 수정할 수 없습니다.
배포 후 공개 경로를 확인하는 방법은 배포 후 smoke test 체크리스트에서 더 자세히 다룹니다. API 에러도 smoke test 대상에 포함되어야 합니다.
에러 처리를 제품 경험으로 보는 기준
- 상태 코드: 클라이언트가 재시도, 로그인 이동, 입력 수정 중 무엇을 해야 하는지 판단할 수 있어야 합니다.
- 사용자 메시지: 내부 원인을 그대로 노출하지 않고 다음 행동을 알려 줍니다.
- 운영 로그: 사용자 메시지와 별개로 원인 추적에 필요한 request id, route, status, duration을 남깁니다.
- 복구 경로: 다시 시도, 임시 저장, 문의, 목록 복귀처럼 사용자가 멈추지 않도록 선택지를 둡니다.
실제 적용 방법
먼저 API 응답 형식을 통일합니다. 예를 들어 code, message, details, requestId를 기본으로 두면 프론트엔드는 오류 유형에 따라 화면을 안정적으로 바꿀 수 있습니다. 유효성 오류는 필드 단위로 보여 주고, 인증 오류는 로그인으로 연결하며, 서버 오류는 요청 ID와 함께 재시도 안내를 제공합니다.
이 구조는 1인 서비스에 필요한 최소 관측성 설계와도 연결됩니다. 사용자에게는 짧은 안내를, 운영자에게는 추적 가능한 로그를 남겨야 장애 시간이 줄어듭니다.
운영 체크리스트
- 400, 401, 403, 404, 409, 429, 500을 같은 메시지로 처리하지 않습니다.
- 사용자에게 보여 주는 문장과 서버 로그 문장을 분리합니다.
- 폼 오류는 필드 근처에 보여 주고, 시스템 오류는 재시도와 문의 경로를 함께 둡니다.
- 관리자 화면에는 request id를 노출해 로그 검색 시간을 줄입니다.
- 에러 문구를 출시 전에 실제 모바일 폭에서 확인합니다.
결론
좋은 API 에러 처리는 실패를 감추는 일이 아니라 사용자가 다음 행동을 선택할 수 있게 만드는 일입니다. 공개 라우트 계약처럼 API 오류도 제품 계약의 일부로 다루면 작은 서비스도 훨씬 안정적으로 보입니다.