콘텐츠로 이동

빌드 때 데이터가 없으면 목록이 빈 채로 구워집니다

데이터를 읽는 화면을 빌드 시점에 미리 그리는 구성에서, 빌드 환경이 그 데이터에 닿지 못하면 빈 목록이 그대로 굳습니다. 오류가 아니라 “글이 없습니다” 로 나가기 때문에 아무도 알아채지 못합니다.

컨테이너 안에서 이미지를 만드는 구성이 특히 그렇습니다. 빌드는 격리된 환경에서 돌고, 운영 데이터베이스는 그 안에서 보이지 않습니다.

세 겹이 겹쳐서 조용해집니다.

첫째, 데이터 계층이 실패를 삼킵니다. 목록을 읽다 실패했을 때 예외를 던지면 빌드가 통째로 멈추므로, 대개 빈 배열을 돌려주도록 짜여 있습니다. 합리적인 선택인데 그 결과가 “데이터가 없음” 과 구분되지 않습니다.

둘째, 빈 상태 화면이 정상적으로 생겼습니다. 잘 만든 사이트일수록 빈 목록을 예쁘게 처리합니다. 오류 화면이 아니라 “아직 올린 글이 없습니다” 가 나옵니다.

셋째, 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 이라 통과 항목 수를 셈