노트
Next.js 서버 액션과 router.push가 프록시 뒤에서 서로를 죽이는 문제
이 사이트를 만들면서 만난 버그 기록.
증상
관리자 에디터에서 글을 저장하면 "저장 중…"이 영원히 끝나지 않는다. 그런데 글은 DB에 정상적으로 생성되어 있다. 로컬에서는 재현되지 않고, Cloudflare Tunnel을 거친 프로덕션에서만 발생.
원인
서버 액션이 revalidatePath를 호출하면 Next 클라이언트는 현재 라우트의 RSC 데이터를 자동으로 다시 가져온다. 그 직후 우리 코드가 router.push를 호출하면 두 개의 RSC fetch가 동시에 뜨는데, 왕복 지연이 ~0.9초쯤 되면 서로가 서로를 abort시킨다:
FAILED: GET /admin/posts?saved=32&_rsc=... | net::ERR_ABORTED
FAILED: GET /admin/new?_rsc=... | net::ERR_ABORTED
둘 다 죽으니 내비게이션도, 화면 갱신도 일어나지 않는다. 로컬은 fetch가 수십 ms 만에 끝나 경합 창이 사실상 0이라 절대 재현되지 않는다.
해결
1인 관리자 페이지라는 맥락에서 가장 확실한 방법을 골랐다 — 저장 성공 후 window.location.assign으로 전체 내비게이션. RSC 경합 자체가 사라진다.
교훈
- 지연이 있어야만 열리는 경합 창이 있다. 로컬 E2E가 전부 통과해도 실제 배포 경로에서 다시 돌려야 하는 이유.
- 디버깅은 이분법으로: 터널 우회(ssh -L) 비교로 프록시/앱을 가르고, curl 재현 실패로 네트워크/클라이언트를 가르고,
requestfailed이벤트로 확정.
조회 1댓글 0
댓글
아직 댓글이 없습니다. 첫 댓글을 남겨보세요.