Skip to main content

Command Palette

Search for a command to run...

JS Date로 인한 버그 트러블 슈팅 회고

버그 해결에 대한 타임라인 정리, 회고를 해보겠습니다.

Updated
2 min readView as Markdown
JS Date로 인한 버그 트러블 슈팅 회고
T

Software engineer for web tech. Interested in sustainable growth as software engineer.

주말 동안 서비스 하고 있는 홈페이지에서 문제를 해결한 경험을 간단하게 기록으로 남기고자 글을 씁니다. 다만 Date 객체의 특수한 스펙이 문제 원인이었다 이런 내용은 아니고 단순히 문제가 발생한 상황에서 어떻게 대응했는지, 그리고 어떤 식으로 예방할 수 있었는지 회고하는 글입니다.

트러블 슈팅 타임라인

문제 발생

  • 평화로운 일요일, 서비스 하고 있는 홈페이지의 제품 마감 시간이 하루가 땡겨져서 동작하고 있다는 청천벽력의 소식을 전화로 급히 전해 들었습니다.(서비스 특성 상 마감시간이 매우 중요합니다)

  • 뭐가 문제인지는 모르겠지만, 일단 개발 DB등에 접근하려면 폐쇄망에 들어가야 합니다. 마음을 다잡으며 vpn을 켰습니다.

원인 추측

  • 리스트 페이지에서는 마감일시가 정상적으로 표시되고 있었다.

  • 상세 페이지에서는 마감시간만 이상하게 하루가 날라간 채로 동작하고 있다.

  • network 탭을 통해 api에서 날라오는 데이터가 정상인지 먼저 확인하자

  • 아니면 javascript 동작 문제를 찾아보자

대충 이런 식의 사고 흐름을 생각하면서 노트북 부팅과 연결 시간을 보냈습니다.

디버깅 단계

  • 먼저 네트워크 탭 살펴보니 데이터는 정상

  • 마감시간을 처리하는 DOM 처리 하는 코드 쪽을 보니 데이터 넘어가는 거 정상

  • 하지만 DOM의 처리 결과는 마감시간이 하루 먼저 땡겨져서 동작하는거 확인

  • 데이터로 받은 시간을 Date 객체로 변환한후 현재 시간과 마감시간의 diff 를 계산하는 함수 코드에서 결과가 비정상으로 넘어오는 것 확인

  • diff를 계산하는 함수 코드 한줄씩 데이터 파싱 되는 부분 추적

  • 괴상한 매직 넘버 발견.

      // 실제 문제 됐던 코드의 일부입니다.
      org = new Date(org.getFullYear(), org.getMonth() + 1, org.getDate(), org.getHours(), org.getMinutes(), org.getSeconds());
      target = new Date(target.getFullYear(), target.getMonth() + 1, target.getDate(), target.getHours(), target.getMinutes(), target.getSeconds());
    
  • 3월의 말일이라는 오늘의 날짜와 마감시간이 4월의 첫날이라는 조건이 만나 마감시간이 기적처럼 하루가 날아가는 현상 발견

    • date 두개 diff를 계산할때 org이 3월 31일 이었고 target이 4월 1일이었습니다.

    • 둘다 1개월씩 추가되니 전자는 5월 1일이 되버렸고(4월은 30일까지임), 후자도 5월 1일이 되버리는 문제가 있어서 하루 먼저 마감이 발생하는 버그였습니다.

    • 0부터(1월이 0) 시작하는 getMonth의 반환 값을 보고 1을 더한게 아닐까 추측해봅니다.

해결 과정

  • 개발 환경 -> 테스트 환경 -> 최종 운영 환경 반영

  • 이터레이션

    • 데이터를 동일하게 세팅

    • 문제 재현 확인

    • 매직 넘버 제거

    • 정상 동작 확인

  • 상황 종료, 이 과정이 약 1시간 소요 됐습니다.

문제를 예방하거나 조기에 대응하기 위한 고민

  1. 테스트 코드 도입: 제일 먼저 생각하는 건 역시 테스트 코드였습니다. 함수 단위에서 문제가 발생하는 것은 테스트를 작성할 때 많이 예방 되는 편입니다.

  2. 시간 처리 라이브러리 도입: dayjs나, date-fns 같은 시간 처리를 위해 특화된 라이브러리를 도입하는 것 또한 좋은 옵션이 될 수 있을 것 같습니다.

마치며

간단한 트러블 슈팅 사례를 기록으로 남겨 봤습니다. 이런 연습을 통해 나중에 큰 문제를 해결하는데도 문제를 체계적으로 대응하는데 도움이 될 거라고 생각하여 글로 정리해봤습니다.

More from this blog

프론트엔드는 경계를 다루는 직무가 되어간다

프론트엔드는 원래도 복잡했습니다. 브라우저마다 다른 렌더링, 상태 동기화, 성능, 접근성 — 화면 하나 제대로 만드는 데 신경 쓸 게 늘 많았습니다. 다만 그 복잡함은 대체로 한 방향을 향했습니다. 이 UI를 어떻게 만들까, 상태를 어떻게 관리할까, 클릭하면 무엇이 바뀌어야 할까. 그런데 요즘 질문의 축이 하나 더 늘고 있습니다. 이 UI는 서버에서 먼저

Jul 20, 20266 min read

AI가 코드를 짜는 시대, 나는 리뷰를 못 따라가고 있었다

솔직히 말하면, 요즘 PR을 제때 리뷰하지 못하고 있습니다. 개발 속도는 빨라졌는데 리뷰 속도는 그대로입니다. 예전엔 하루 이틀이면 처리하던 게 이제는 며칠씩 밀립니다. 처음엔 제가 게을러진 탓인가 싶었습니다. 돌아보니 그게 아니었습니다. AI 도구를 쓰면서 코드가 쏟아지는 속도가 달라졌습니다. 한 사람이 만들어내는 코드 양이 예전과 비교가 안 됩니다. P

Mar 18, 20263 min read
AI가 코드를 짜는 시대, 나는 리뷰를 못 따라가고 있었다

테드풀의 한 입 지식

78 posts

가볍게 정리하는 기록들입니다.