빌드 때 데이터가 없으면 목록이 빈 채로 구워집니다
데이터를 읽는 화면을 빌드 시점에 미리 그리는 구성에서, 빌드 환경이 그 데이터에 닿지 못하면 빈 목록이 그대로 굳습니다. 오류가 아니라 “글이 없습니다” 로 나가기 때문에 아무도 알아채지 못합니다.
컨테이너 안에서 이미지를 만드는 구성이 특히 그렇습니다. 빌드는 격리된 환경에서 돌고, 운영 데이터베이스는 그 안에서 보이지 않습니다.
왜 조용한가
섹션 제목: “왜 조용한가”세 겹이 겹쳐서 조용해집니다.
첫째, 데이터 계층이 실패를 삼킵니다. 목록을 읽다 실패했을 때 예외를 던지면 빌드가 통째로 멈추므로, 대개 빈 배열을 돌려주도록 짜여 있습니다. 합리적인 선택인데 그 결과가 “데이터가 없음” 과 구분되지 않습니다.
둘째, 빈 상태 화면이 정상적으로 생겼습니다. 잘 만든 사이트일수록 빈 목록을 예쁘게 처리합니다. 오류 화면이 아니라 “아직 올린 글이 없습니다” 가 나옵니다.
셋째, 200 을 줍니다. 배포 검증이 주소를 두드려 상태 코드만 본다면 통과합니다.
재생성은 요청이 있어야 일어납니다
섹션 제목: “재생성은 요청이 있어야 일어납니다”빌드 뒤 일정 주기로 다시 만드는 방식(ISR 류)을 쓰면 괜찮다고 생각하기 쉽습니다. 실제로는 요청이 들어와야 다시 만들어집니다. 아무도 안 오면 영원히 빈 버전이 나갑니다.
트래픽이 없는 사이트에서 이게 특히 아픕니다. 갓 만든 사이트, 방금 올린 새 화면 — 하필 첫 방문자가 가장 나쁜 버전을 봅니다.
이 사이트에서도 검토를 마친 글이 열 편 있는데 목록과 첫 화면이 모두 “글이 없습니다” 를 보여주고 있었습니다. 두 번 두드리고 나서야 실제 제목이 나왔습니다.
어떻게 잡나
섹션 제목: “어떻게 잡나”빌드 단계와 런타임 실패를 구분하십시오
섹션 제목: “빌드 단계와 런타임 실패를 구분하십시오”빈 배열을 돌려주더라도 왜 비었는지는 구분할 수 있어야 합니다.
async function load(where) { // 빌드 중에는 데이터에 닿지 않는 것이 정상이다. 조용히 넘어간다. if (isBuildPhase()) return []
try { return await readFromDatabase(where) } catch (error) { // 런타임에 여기 들어왔다면 장애다. 조용히 넘기면 사이트는 200 을 주면서 // 목록만 통째로 사라지고 아무도 알아채지 못한다. console.error('[posts] 읽지 못해 빈 목록으로 응답합니다.', error) return [] }}빈 응답은 같지만 흔적이 남습니다. 운영에서 목록이 비었을 때 로그를 보면 원인이 바로 나옵니다.
배포 뒤에 한 번 데워 두십시오
섹션 제목: “배포 뒤에 한 번 데워 두십시오”재생성이 요청으로 일어난다면, 첫 방문자가 오기 전에 우리가 먼저 두드리면 됩니다.
한 번 두드리는 것으로는 부족합니다. 첫 요청은 재생성을 걸 뿐이고 그 응답은 여전히 옛 버전입니다. 재생성은 뒤에서 돌고, 끝날 때까지 시간이 걸립니다. 새 버전이 나올 때까지 두드리며 기다려야 합니다.
200 이 아니라 알맹이를 확인하십시오
섹션 제목: “200 이 아니라 알맹이를 확인하십시오”이게 결정적입니다. 목록 화면이면 항목 링크 수를 세십시오.
const count = html .match(/href="\/posts\/[a-z0-9-]+"/g) ?.filter((h) => !isCategoryPath(h)).length ?? 0
if (count === 0) fail('목록에 항목이 하나도 없다')언젠가 정말 0 이 될 수 있습니다
섹션 제목: “언젠가 정말 0 이 될 수 있습니다”항목이 하나라도 있어야 통과하는 검사는, 글을 전부 내리는 날 실패합니다. 그때 이 검사를 지워야 한다는 것을 검사 옆에 적어 두십시오. 몇 달 뒤에 이 실패를 보는 사람은 그 사정을 모릅니다.
애초에 미리 그리지 않는 선택
섹션 제목: “애초에 미리 그리지 않는 선택”데이터가 자주 바뀌는 화면이라면 빌드 시점에 그리지 않는 방법도 있습니다. 요청마다 그리면 이 문제가 생기지 않습니다.
대신 응답이 느려지고 데이터베이스가 매 요청을 받습니다. 글 목록처럼 하루에 몇 번 바뀔까 말까 한 것에는 과합니다.
어느 쪽을 고르든 검증은 필요합니다. 미리 그리는 쪽은 빈 채로 굳는 것을, 요청마다 그리는 쪽은 장애가 났을 때 빈 목록으로 나가는 것을 잡아야 합니다. 증상이 같습니다.
| 증상 | 대응 | |
|---|---|---|
| 빌드에 데이터 없음 | 빈 목록이 굳음 | 빌드 단계를 구분해 삼키고, 런타임 실패는 남김 |
| 재생성이 안 일어남 | 옛 버전이 계속 나감 | 배포 뒤 새 버전이 나올 때까지 두드림 |
| 검증이 못 잡음 | 200 이라 통과 | 항목 수를 셈 |
