Chrome DevTools Local Overrides로 API 에러 응답 재현하기
백엔드가 아직 특정 에러 응답을 내려줄 수 없을 때, 프론트엔드의 에러 처리 로직을 확인하는 방법이다. 서비스 함수를 임시로 목업했다가 정작 확인하려던 axios 인터셉터 흐름을 통째로 건너뛴 경험을 계기로 정리했다.
서비스 함수 목업의 함정
에러 처리(토스트, 리다이렉트, 에러 바운더리)를 확인하려면 실제로 그 에러가 나야 한다. 흔히 떠올리는 방법은 서비스 함수를 잠깐 바꾸는 것이다.
// ❌ 네트워크 요청 자체가 발생하지 않는다
export const getUserMe = async () =>
Promise.resolve({ data: { code: 100, message: '권한 없음', data: {} } });
이렇게 하면 axios 요청이 아예 나가지 않는다. axios 인터셉터, 재시도, 에러 바운더리로 이어지는 흐름은 실제 HTTP 응답을 받아야 동작하므로 전부 건너뛰게 된다. "토스트가 왜 안 뜨지?"라며 헤매기 쉽다.
필요한 것은 요청은 실제로 보내고, 응답만 원하는 값으로 바꾸는 것이다.
Local Overrides
Chrome DevTools의 Local Overrides는 네트워크 응답을 로컬 디스크에 저장한 파일로 대체한다. 서버나 프론트엔드 코드를 건드리지 않고 특정 요청의 응답 본문(과 헤더)을 고정할 수 있다.
개입 지점이 브라우저 네트워크 계층이라, 애플리케이션 코드(axios 인터셉터, React Query, 에러 바운더리)는 진짜 서버 응답과 구분하지 못한다. 실제 운영 흐름 그대로 검증할 수 있다.
사용법
- 재현할 요청이 발생하는 화면으로 이동한다.
- DevTools → Network 탭에서 해당 요청을 우클릭 → Override content.
- 처음 한 번은 오버라이드 파일을 저장할 로컬 폴더를 지정하고 권한을 허용한다.
- 열린 편집기에서 응답 본문을 수정하고 저장한다.
- 새로고침하면 이후 같은 요청은 수정한 응답을 받는다.
Sources → Overrides 패널에서 폴더를 미리 지정하고 파일을 직접 편집할 수도 있다. 오버라이드가 켜져 있는 동안 Network 탭의 해당 요청에 표시가 붙으므로, 확인이 끝나면 꼭 끄거나 파일을 지운다.
예: 비즈니스 에러 코드 재현
HTTP 상태는 200인데 본문의 code로 실패를 구분하는 API가 많다. 권한 없음 같은 경우는 계정 권한을 실제로 바꾸지 않고도 바로 재현할 수 있다.
// 원본
{ "code": 0, "message": "success", "data": { "...": "..." } }
// 오버라이드
{ "code": 100, "message": "권한이 없습니다", "data": {} }
이 상태에서 다음을 실제 흐름 그대로 확인했다.
- 응답 인터셉터가 이 응답을 잡아 토스트를 띄우는가
- React Query 재시도가 이 코드에서 멈추는가, 아니면 재시도하면서 토스트가 여러 번 뜨는가
- 에러 바운더리가 의도한 화면을 보여주는가
"다시 시도"를 눌러도 오버라이드가 유지되므로 재시도 동작도 반복해서 확인할 수 있다.
한계와 대안
- 공유가 안 된다: 내 브라우저의 로컬 폴더에 묶여 있어 다른 사람이나 CI에서 재현할 수 없다. 재현 방법은 따로 문서로 남긴다.
- 수동 설정: 브라우저를 바꾸거나 폴더 권한이 사라지면 다시 설정해야 한다.
- 자동화 테스트에 부적합: 팀이 반복해서 돌려야 하는 시나리오는 MSW나 Playwright
page.route()처럼 코드로 정의하고 버전 관리하는 목업으로 옮긴다.
정리
| 상황 | 방법 |
|---|---|
| 특정 에러 응답을 지금 바로 눈으로 확인 | DevTools Local Overrides |
| 반복 실행할 회귀 테스트로 남기기 | MSW / Playwright mock |
| 서비스 함수를 직접 바꿔 재현 | ❌ 인터셉터·재시도·에러 바운더리를 우회함 |