[TIL] 2. Script, Axios 그리고 묻히는 에러

MinseoKim·2026년 7월 31일

1. 오늘의 한 줄 요약

Promise의 상태 흐름과 Axios 메서드를 배우고 실습했는데, 정작 가장 크게 배운 건 코드 문법이 아니라 .then/.catch가 에러를 조용히 묻어 사실이었다.

2. 배운 내용

★ 핵심 개념

오늘은 ES6의 PromiseAxios 실습을 진행했다.

Promise는 비동기(client-server) 작업의 처리를 도와주는 객체다.

new Promise((resolve, reject) => {
});

상태(state)는 다음 흐름으로 진행된다.

  • pending(초기화) → resolve 또는 reject 호출 → fulfilled 또는 rejected
  • resolvereject를 통칭해서 settled라고 부른다
  • resultundefined로 초기화되고, resolve(value)value가 서버의 json data를 담는 콜백 역할을 한다. reject는 error를 담는다.

Axios는 script 기반 SPA에서 주로 사용하며, 다음 특징을 정리했다.

  • .finally(() => {}): 성공/실패 여부와 상관없이 마지막에 무조건 실행됨
  • post는 인캡슐레이션 때문에 xxxx?queryString처럼 쿼리 스트링이 붙지 않음
  • patch는 일부 수정, put은 전체 수정 (리소스 소모가 큼)
  • delete
  • 경로에 /1처럼 붙는 방식은 path variable 방식

새롭게 알게 된 점

개념 보완

  1. imgtextContent가 아니라 src로 지정한다
  • img 태그는 텍스트를 담는 태그가 아니라 이미지 경로를 불러오는 태그이기 때문에, 텍스트를 넣는 textContent 대신 src 속성을 써야 한다는 걸 다시 확인했다.

    image.src = object.image;
    image.alt = object.title; // 접근성 보완
  1. const/let의 블록 스코프 때문에 생긴 card is not defined
  • forEach 콜백 에서 const card를 선언해놓고, card.appendChild(...)는 콜백 에서 호출하는 실수를 했다.
  • const/let은 블록 스코프이기 때문에, forEach 콜백이 끝나는 순간 그 안에서 만든 변수는 전부 사라진다. 카드 생성 → 조립 → appendChild까지 전부 forEach 콜백 안에서 끝내야 한다.
    // 잘못된 예
    ary.forEach((object, idx) => {
        const card = document.createElement('div');
        // ...
    });
    card.appendChild(image); // card는 이미 스코프 밖

에러 관련

3. .then/.catch 체인이 오타로 인한 에러를 가리는 문제

  • 가장 오래 걸렸던 에러 해결은 responserespose로 오타 낸 것이었다.이 부분은 AI를 사용하기 전까지 계속 문제를 찾아내지 못하고 있었다.
.then(response => {
    ary = respose.data; // response 아니라 respose (오타)
})
.catch(error => {
    console.log(`debug >>>> error ${error}`);
});
  • respose는 정의되지 않은 변수라 ReferenceError가 발생하는데, 바로 뒤에 연결된 .catch()가 이 에러를 조용히 넘겨받아버려서 화면에는 빨간 에러가 전혀 뜨지 않았다. 콘솔에 debug >>>> error ... 로그만 조용히 찍히고 지나갔다.

여기서 얻은 깨달음은, "화면에 에러가 안 뜬다 = 코드가 정상이다"는 아니라는 것이다. .then 안의 모든 에러(오타 포함)는 .catch로 넘어가므로, 콘솔 로그를 항상 확인하는 습관이 필요하다는 것을 느꼈다.

그런데 막상 생각해보니 콘솔로그 에러를 제대로 읽는 방법에 대해 공부해본 적이 없었다..


앞으로 어떻게 에러를 다뤄야 하는가?

4. e.targete.targer로 오타 냈을 때의 에러 읽는 법

Uncaught TypeError: Cannot read properties of undefined (reading 'textContent')

이 메시지를 뒤에서부터 읽으면 원인을 역추론할 수 있다.

  1. 'textContent'를 읽으려 했다 → 무언가.textContent를 쓴 코드를 찾는다
  2. 그 "무언가"가 undefined였다 → e.targer.textContent에서 e.targerundefined
  3. e(이벤트 객체)에는 target은 있어도 targer는 없다 → 오타 확정

Cannot read properties of undefined/null (reading 'xxx') 형태의 에러는 대부분 아래 셋 중 하나가 원인이었다.

원인예시
오타e.targer (target 아님)
DOM에 없는 요소를 선택querySelector('#없는id')null 반환
비동기 데이터가 아직 안 옴fetch 응답 오기 전에 배열 순회

앞으로 더 나은 이슈 해결을 위해 js 에러를 읽는 md파일을 만들었다!

3. 실습 / 적용

직접 해본 것

  • Axios로 fakestoreapi.com/products에서 상품 데이터 받아와 카드 UI로 렌더링
  • 이미지 송출 시 메서드에 따라 다르게 처리하는 방식 실습
  • 삭제 버튼 클릭 시 배열에서 항목 제거 후 재렌더링 (splice + 재호출)
  • 버튼 클릭 이벤트에서 id 사용 방식 / handler 사용 방식 구분

결과

오타와 스코프 문제를 전부 수정한 뒤에는 정상적으로 상품 목록이 카드 형태로 렌더링되었다.

const loadData = async () => {
    await axios.get('https://fakestoreapi.com/products')
        .then(response => {
            ary = response.data;
        })
        .catch(error => {
            console.error(error);
        });
};

const makeProduct = () => {
    container.innerHTML = '';
    ary.forEach((object, idx) => {
        const card = document.createElement('div');
        card.className = 'card';

        const image = document.createElement('img');
        image.src = object.image;
        image.alt = object.title;

        const title = document.createElement('h3');
        title.textContent = object.title;

        const price = document.createElement('p');
        price.textContent = object.price;

        const delBtn = document.createElement('button');
        delBtn.className = 'btn';
        delBtn.textContent = '삭제';
        delBtn.onclick = () => {
            ary.splice(idx, 1);
            makeProduct();
        };

        card.appendChild(image);
        card.appendChild(title);
        card.appendChild(price);
        card.appendChild(delBtn);

        container.appendChild(card);
    });
};

4. 문제와 해결

막힌 부분

가장 오래 붙잡고 있었던 건 respose.data 오타였다. 콘솔에 빨간 에러가 뜨지 않아서 한참을 "왜 데이터가 안 그려지지?"라며 렌더링 로직 쪽만 들여다봤다.

★ 해결 방법

  1. resposeresponse 오타 수정
  2. .catch(error => console.error(error))처럼 에러를 눈에 띄게 로깅
  3. 에러가 안 떠도 항상 콘솔의 로그(특히 debug 로그)를 먼저 확인하는 습관 들이기

이번 실습을 계기로 에러 메시지를 읽는 순서도 정리했다.

  1. 에러 종류 확인 (TypeError / ReferenceError / SyntaxError)
  2. 메시지에서 문제가 된 속성/변수 이름 파악
  3. 그 이름을 코드에서 검색(Ctrl+F)해서 오타나 잘못된 참조 찾기
  4. 애매하면 에러 나는 줄 바로 위에 console.log()로 실제 값 찍어서 확인

5. 다음에 할 일

  • js에러읽는법.md 파일 관련 벨로그 정리하기
  • 버튼 이벤트 감지 관련 실습 코드 유의!(scriptProperty.html)
  • .then/.catch 대신 try/catch + async/await 조합으로 에러 처리 다시 연습

0개의 댓글