Nest 트러블슈팅 + 쌩javascript extension

김태성·2024년 5월 5일
0

내실 다지기

목록 보기
9/11

로그인 403

문제상황
잘되던 로그인이 안된다.

문제 해결 과정

  • 최근에 업데이트된 파일이 있나 git 로그를 확인

  • 보안쪽 업데이트가 있다.

  • 로그인 로직부터 보안 인증까지 console을 찍어보면서 확인한다.

  • header 검증 로직에서 undefine이 뜬다.

    const request = context.switchToHttp().getRequest();
    const authHeader = request.headers['Authorization'];
    if (!authHeader) {
      return false;
    }
  • 이유는 우리가 토큰을 2가지 방식으로 검증하기 때문이다.
    첫째는 로그인 할때 구글에서 보내주는 토큰으로 인증해서 jwt를 발급받는것.
    두번째는 발급받은 jwt로 본인 인증을 하는것.

  • 여기서 구글토큰과 jwt의 형식이 다르기 때문에 오류가 났다.

  • 그러니까 로그인 할때만 예외처리를 해주면 되겠구나.

extension 데이터 전송 실패

문제상황

보고서 페이지를 만들려고 자리비움 기능을 사용하면 아래와 같은 오류가 났다.

내가 만든 기능도 아니라서 막막했는데 한번 찾아봤다.

해결과정

  • 해당 내용을 보면 Bad Request라고 나와있다.

  • 따라서 HTTP 통신 중에 잘못된 형식/데이터를 보낸다고 판단

  • extension 코드에서 졸음이 발생했을때 HTTP 통신을 하는 코드를 찾음.

원인

  • lectureHistories 데이터는 workbookContext에서 찾아야 되는데 analyticsContext에서 보내고 있었다.

  • 처음에는 이것을 어떻게 고칠지 몰랐는데, 비슷한 기능을 가진 다른 코드를 참고해서 lectureHistoryID의 정확한 위치를 찾았다.

어려웠던점

갑자기 에러가 뜨는데 내가 짰던 코드도 아니라서 원인이 어떤것인지 감이 안잡혔다. error 코드를 보고 침착하게 원인을 파악하려고 했던게 도움이 되었다.

AI가 새로 만든 문제집을 풀었을때 에러가 남

문제 상황

우리 프로그램은 AI가 강의 script를 기반으로 문제를 만들어 주는데, 새로 만든 문제는 content가 undefine으로 나와서 에러가 남(그러니까 푼 문제가 없다는 소리)

해결과정

  • 어떻게 flow가 흘러가는지 알아보기 위해서 로직 과정을 다 뜯어봄. 백엔드/extension 2종류의 코드인데 약 8~9페이지에 걸쳐서 있음.

  • 과정은 다음과 같음. extension에서 post -> 서버에서 사용자 문제 풀이 결과 저장 -> 나중에 보고서 만들때 저장된 데이터 전부 반환 -> 보고서 작성

  • debug툴을 사용해서 break point를 찍어가면서 확인하다가 새로 만들어진 문제집은 서버에 결과를 저장하는 post를 발송하지 않는다는것을 확인.

원인 및 해결

위가 AI 문제집 생성 및 반환 코드이고
아래가 푼 문제를 서버에 저장하는 코드이다.

서버에 저장하는 코드에는 choiceId가 필요한데, AI 문제집 생성 후 반환할때 이 Id값을 반환하지 않았다.

그래서 재대로 데이터는 넘어갔지만 choiceId값이 null이니 데이터가 정확하게 전달 될 리도 없었고, 그래서 푼 문제들도 content empty가 떠서 보이지 않았던 것이다.

하지만 문제 데이터는 데이터베이스에 잘 남아있으니
만들어진 문제집으로 문제를 풀때는 choiceId까지 가져오기 때문에 문제가 발생하지 않았다.

진짜 찾기 힘들었던 버그이다.

modal창 중첩 버그

문제상황
extension에서 문제를 풀때 자리비움/졸음 모달창이 뜸.
더 심각한거는 자리비움/졸음 모달을 끌때 강의가 실행이 되어버림

원인

const capture = () => {
    context.drawImage(video, 0, 0, canvas.width, canvas.height);
      LoaAxios.postFile(
        `${IMAGE_PROCESSING_HOST}/api/image-process/image`,
        canvas.toDataURL('image/jpeg'), 
        (response) => {
              if(response.isExist && response.isEyeClosed){
                analyticsContext.sleepCount = analyticsContext.sleepCount + 1;
              }
              else if(!response.isExist){
                analyticsContext.existCount = analyticsContext.existCount +1;
              }
              else{
                analyticsContext.sleepCount = 0;
                analyticsContext.existCount = 0;
              }
              if(analyticsContext.sleepCount == 5){
                  analyticsContext.startedAt = formatDate(new Date());
                  showWakeUpModal();
              }
              else if(analyticsContext.existCount == 5){
                  analyticsContext.startedAt = formatDate(new Date());
                  showLeaveSeatModal();
              }
        }
      );
  };

웹캠을 이용해서 졸음/자리비움을 감지하는 코드이다.
문제를 풀때도 지속적으로 사진을 캡쳐해서 서버로 보내기 때문에
졸음/자리비움 모달이 계속 발생한다.

해결방안

~~
  // modal이 떠있을때는 post를 못하게 막는다.
   if(!document.querySelector("#quiz-modal")) {
      LoaAxios.postFile(
~~

간단하게 모달창이 떴을때는 post를 보내지 않도록 한다.
그 이유에 대해서는 다음과 같다.

  • 우리 extension에는 문제/졸음/자리비움 3가지의 모달창이 있음.

  • 문제를 풀때 졸음/자리비움을 막아버린다면 문제의 우선순위가 가장 올라감.

  • 졸음/자리비움 등등 시간을 보내는 기준은 new Date()기준이라 중간에 통신이 끊어져도 상관이 없음. 시작과 끝 시간만 잘 보내면 됨.

  • 또한 capture 함수가 진행되고 있다면 계속해서 캡쳐는 하는 것임으로
    문제를 풀고 난 직후부터 졸음/자리비움 감지가 시작 될 수 있음.

 const capture = () => {
   //내부 코드
   
 }
   
  • 즉 나올 수 있는 모든 경우의 수를 예측해봤을때 최선이라고 생각을 했음.
    물론 생각지도 못한 버그가 있다면 고쳐야 함.

어려웠던점
QA를 할때 항상 느끼는거지만 한번도 못봤던(다른 팀원이 짰던)코드를 flow만 읽고 어떤 기능인지 해석을 한 후 필요한 기능을 추가해야 하는데, 그러한 독해 과정이 힘들었음. 코드를 많이 읽으면서 코드 해독 능력을 키워야겠다고 생각했고, 클린 코드의 필요성을 계속해서 느끼는중

익스텐션 모달창 움직임 버그

문제상황
크롬 익스텐션 모달창이 특정 사이트에서는 정상적으로 작동하지 않았음.
모든 페이지에서 그러는것도 아니고 특정 페이지에서만 안됨.

원인

   navbar.style.left = 'calc(100% - 310px)'

모달창이 로딩될때 특정 위치를 기준으로 로딩이 되는데, 웹 사이트의 css와 충돌이 나서 안됐던거 같다.

잘 움직이는 사이트의 페이지와 잘못 움직이는 페이지의 css가 달랐음.

어려웠던점
왜 안되는지 감도 안잡혔던 문제는 처음이었던거 같다.
구글링도 실력이라는걸 알았다.

비동기 데이터 전달 오류.1

문제상황
크롬 익스텐션으로 브라우저에 모달 창을 하나 만든다음, 그 모달창 안에 iframe으로 사이트를 로딩함.
익스텐션 -> 사이트 방향으로 데이터를 전달하는데, 분명히 await 비동기 순서를 잘 확인했음에도 안됨.

원인

(재대로 데이터 받아와 놓고 warning을 갱신해 박살나버리는 데이터들)

2일간 머리싸매고 문제를 전혀 몰라서 스트레스 잔뜩 받았는데 warning 오류메세지 때문이었다.
모달창 안의 iframe으로 데이터를 넣기 위해서 EventListener를 통해 message를 보내고 있었는데,
이때 warning도 message로 인식해서 데이터를 갱신하고 있었던 것이다..
도대체가 key값도 다른데 왜 갱신이 되는건지 몰라서 또 스트레스 잔뜩 받고 있지만
잘못된 message를 받아서 데이터가 잘못 갱신이 되는것이니 해결은 간단했다.

해결방법

            if (
                !event.origin || 
                !event.data ||
                typeof event.data.courseTitle !== 'string' ||
                typeof event.data.subCourseTitle !== 'string' ||
                typeof event.data.playTime !== 'string' ||
                typeof event.data.currentURL !== 'string' ||
                (event.data.iframeQuizzes && !Array.isArray(event.data.iframeQuizzes)) ||
                typeof event.data.authToken !== 'string'
            ) {
                console.log('Invalid data format');
                return;
            }

데이터 무결성 검사 장치를 만들어 줬다.
message를 검사해서 원하는 message가 아니라면 return 으로 종료시키는 코드이다.

비동기 데이터 전달 오류.2

문제상황
잘 되던 코드가 배포를 하니 전달 console 자체가 찍히지 않는다.

원인
정확하게 파악된건 아니지만 데이터를 보낸다는 console은 찍히지만 받는다는 console이 찍히지 않는것을
보니 데이터를 보낸 후 페이지가 로딩이 된다고 판단을 했다.

해결방안


messageIntervalRef.current = window.setInterval(() => {
    console.log('require data (interval)');
    window.parent.postMessage(
        { functionName: 'requiredata' }
        , '*'
    );
}, 10);
// 데이터를 익스텐션으로 요청하는 코드


window.addEventListener('message', (e) => {
    if (e.data.functionName === 'requiredata') {
    console.log('post iframe data', dataToSend);
    iframe.contentWindow?.postMessage(dataToSend, '*');
    }
});
//요청한 데이터를 모달 안의 iframe 안의 클라이언트로 내려보내는 코드

데이터 전송 로직을 바꿨다.

  • 기존 : 페이지가 로딩되는것과 상관없이 페이지 로딩을 시키고 데이터를 이후에 보냄.
  • 변경 : 페이지가 로딩되었을때 익스텐션으로 데이터를 요청하고, 요청을 받은 익스텐션이 클라이언트로 데이터를 전송

즉, 페이지가 로딩이 된 후 데이터를 보낸다는것이 확실해졌다.

슬픈점

    const courseDataRef = useRef({ courseTitle: '', subCourseTitle: '', playTime: '' });

ref라는 hook이 있어서 썼었는데, 정신차리고 보니까 이게 중복되어서 쓸모 없는 코드였다.
그래서 지웠더니 위에서 해결했던 비동기 순서 로직 상관없이 잘 되었다.
정확한 이유는 잘 모르지만 로딩 시간을 늘렸다고 예상된다.

profile
닭이 되고싶은 병아리

0개의 댓글

관련 채용 정보