문제 상황

image.png

image.png

프론트/백엔드 파트장 투표 후 “현재 투표 순위 보러가기” 누르면 404 에러가 발생하였습니다. 다만, 일부 로컬에서는 정상적으로 작동하지만 일부 로컬에서 404 에러 발생하였기 때문에 명확한 원인을 찾지 못한 상태에서 버그 수정을 진행했습니다.

원인 분석

정상적으로 URL이 연결되는데 개발 서버가 라우트를 제대로 인식하지 못하거나 잘못된 part 값이 그대로 코드에 들어갈 수 있는 구조라 판단하였습니다.

// 기존 코드
const part = params.part as LeaderPart;
const apiPart = LEADER_PART_TO_API_PART[part];
const voteConfig = LEADER_CONFIGS[part];

router.push(`/vote/leader/${part}/ranking`);

as LeaderPart는 타입 단언일 뿐 실제 값을 검증하지 않습니다. 런타임에서 part가 예상과 다른 값으로 들어오면 apiPart, voteConfig, 이동 URL이 모두 불안정해질 수 있다고 판단했습니다.

해결

  1. part 값 런타임 검증 추가

    export const isLeaderPart = (part: string | string[] | undefined): part is LeaderPart =>
      typeof part === "string" && Object.prototype.hasOwnProperty.call(LEADER_CONFIGS, part);
    

    frontend / backend가 아닌 값이 들어오면 즉시 notFound()로 처리해 이후 로직이 실행되지 않도록 했습니다.

  2. 순위 이동 URL을 상수로 고정

    rankingHref: "/vote/leader/backend/ranking"
    
    // 기존
    router.push(`/vote/leader/${part}/ranking`);
    // 변경
    router.push(voteConfig.rankingHref);
    

    런타임 값으로 경로를 조합하는 대신, 검증된 설정 객체에 명시된 경로를 사용해 잘못된 URL이 생성될 여지를 없앴습니다.

  3. API 오류 처리 보강

    투표 API 응답 파싱 실패 / success: false / 결과 조회 실패 시 기존 에러 문구를 그대로 노출하도록 처리했습니다.

    동적 라우트의 part 값을 검증 기반으로 수정하고, 순위 이동 경로를 명시적으로 고정해 404가 발생할 수 있는 경우의 수를 줄였습니다.

배운 점

일부 로컬에서만 문제가 발생해도 보통 원인을 파악할 수 있는데 개발자 도구 내에서 관련 문제를 찾을 수 없어 직접 에러에 대해 고민하고 코드를 여러 번 확인하며 라우트에 대해 고민할 수 있었습니다.

이 과정을 통해 예상 가능한 오류 및 예외에 대해 생각하며 코드의 구조를 생각할 수 있게 되었고, 예상치 못한 문제가 발생해도 다방면으로 오류를 찾을 수 있는 기회가 되었습니다.