화면에 목록이 하나도 안 나오는데 어떤 오류 메시지도 함께 뜨지 않았다. 개발자 도구로 확인해 보니 요청은 정상 응답이었고 본문 내용도 들어 있었다.
Table of contents
Open Table of contents
200인데 빈 화면
요청 자체는 성공했고 응답 본문을 파싱하는 것도 아무 문제 없이 끝났다. 실제로 실패한 자리는 그 응답을 받아서 다루는 그다음 처리 쪽이었다.
예외 처리 구간 밖에서 일어나거나 렌더링 쪽이 삼키면 오류 표시 없이 빈 화면만 남는다. 요청 성공 여부만 보는 오류 처리는 응답 이후의 실패를 통째로 못 잡는다.
봉투 객체와 배열 타입
응답 본문을 열어 보니 결과 배열과 실패 배열을 함께 담은 봉투 객체였다. 그런데 화면 쪽 코드는 그것을 배열로 타입해 두고 받자마자 순회하고 있었다.
객체를 배열처럼 다루면 그 자리에서 실패하는데 그 실패가 렌더링 안에서 일어나 조용히 빈 화면이 됐다. 응답이 배열로 온다는 전제가 코드 어디에서도 검증되지 않고 있었다.
타입 선언과 런타임 값
타입이 선언돼 있으니 맞을 것으로 봤지만 타입 선언은 작성 시점의 약속이고 런타임에 오는 값과 다를 수 있다. 서버가 응답 모양을 바꾸더라도 화면 쪽의 타입 선언은 그대로 남아 있게 된다.
그래서 라우트 단위로 실제 응답을 받아 타입 선언과 대조했더니 안 맞는 곳이 여럿이었다. 타입 선언을 믿는 것과 실제 응답을 받아서 확인하는 것은 서로 다른 일이었다.
문자열로 오는 소수
대조하는 과정에서 소수 필드가 숫자가 아니라 문자열로 온다는 것도 확인했다. 서버 쪽 라이브러리가 정밀도를 지키려고 기본값으로 문자열 직렬화를 하고 있었다.
그 값을 그대로 곱하면 계산이 안 되고 더하면 문자열이 그대로 이어 붙는다. 뒤쪽이 특히 나쁜데 오류가 나지 않은 채로 그럴듯한 값이 만들어지기 때문이다.
권한과 낡은 주석
편집 화면을 만들었는데 저장이 항상 거부되어 확인하니 그 경로는 다른 종류의 계정만 쓸 수 있었다. 같은 리소스여도 조회와 수정의 요구 권한이 다를 수 있으므로 화면을 만들기 전에 확인할 항목이었다.
파일 상단에는 백엔드가 미구현이라 임시 데이터를 쓴다는 주석이 있었는데 실제로는 이미 구현돼 있었다. 주석보다 실제 경로를 확인해야 했고 이번 정리는 보고받은 내용을 옮긴 것이라 직접 재검증하지 못했다는 근거 수준도 함께 적었다.
정리
- 응답 모양이 달라도 요청은 성공으로 끝난다
- 요청 성공만 보는 오류 처리는 그 뒤의 실패를 못 잡는다
- 배열인 줄 알았던 응답이 봉투 객체일 수 있다
- 타입 선언은 검증이 아니라 작성 시점의 약속이다
- 라우트 단위로 실제 응답과 대조한다
- 소수 필드가 문자열로 오면 오류 없이 값만 틀린다
- 같은 리소스여도 조회와 수정의 요구 권한이 다를 수 있다
- 주석은 낡으므로 실제 경로를 확인하고 근거 수준을 적는다