소프트박스

News

소프트박스의 새로운 소식을 알려드립니다.

기술에 감성을 더한 소프트웨어로 창의적이고 혁신적인 문화를 만들어가는
소프트박스의 진솔한 이야기를 전합니다.

IT칼럼

프론트엔드 개발을 진행하다 보면 예기치 못한 에러가 자주 발생합니다. 특히 주니어 개발자라
2025-03-20 오전 11:25:00

프론트엔드 개발을 진행하다 보면 예기치 못한 에러가 자주 발생합니다. 특히 주니어 개발자라면 에러 메시지를 접했을 때, 당황스럽고 어디서부터 손을 대야 할지 막막할 수 있죠.

 

하지만 걱정할 필요는 없습니다. 경험이 쌓여 시니어 개발자가 되면, 에러 메시지는 오히려 문제를 사전에 방지할 수 있는 중요한 신호로 여겨집니다. 에러 없이 릴리즈된 소프트웨어가 나중에 더 큰 문제를 야기할 수 있기 때문이죠. 시니어 개발자는 수많은 에러를 겪어보았기에, 새로운 에러가 나타나더라도 다양한 해결 방법을 찾아낼 수 있습니다.

 

실제로 프로그램 개발 과정에서 에러 조사와 수정에 드는 시간은 전체 업무 시간의 약 40%에 달한다고 알려져 있습니다. 따라서 에러를 효과적으로 처리하는 능력은 개발자에게 필수적인 역량입니다. 아무리 많은 경험을 쌓더라도 모든 종류의 에러를 직접 경험할 수는 없으므로, 에러 발생 시 이를 신속하게 분석하고 해결할 수 있는 능력을 키우는 것이 중요하죠. 이번 글에서는 프론트엔드 개발자가 자주 만나는 에러의 유형과 해결 방법 등을 살펴보겠습니다.

 

<출처: Flux AI, 작가 제작>

에러를 만났습니다

<출처: 요즘IT, 작가 캡처>

 

에러가 발생하면 대부분의 개발 환경은 “에러가 발생했어요”라고 친절하게 알려줍니다. 에러를 효과적으로 해결하려면, 먼저 에러 메시지가 어떻게 구성되어 있는지 이해하는 것이 중요합니다. 에러 메시지는 문제의 원인을 파악할 수 있는 핵심 정보를 제공하며, 이를 분석하는 것이 에러를 다루는 첫걸음입니다.

 

대부분의 프로그래밍 언어에서 에러 메시지는 다음과 같은 요소로 구성됩니다.

 

  • 에러 유형(Error Type): 발생한 오류의 종류를 나타냅니다.
  • 에러 메시지(Error Message): 오류의 원인에 대한 설명을 제공합니다.
  • 스택 트레이스(Stack Trace): 오류가 발생한 코드 실행 흐름을 보여줍니다.

 

예를 들어, 다음과 같은 에러 메시지를 살펴봅시다.

 

TypeError: Cannot read properties of undefined (reading `name`) at Object.getUserName (app.js:10) at fetchUserData (app.js:25) at main (app.js:40)

 

위 메시지는 TypeError가 발생했으며, undefined인 객체에서 name 속성을 읽으려 했을 때 문제가 발생했음을 의미합니다. 또한 app.js 파일의 10번째 줄에서 getUserName 함수가 호출될 때 에러가 발생했고, 그 호출이 fetchUserData 함수(25번째 줄)와 main 함수(40번째 줄)에서 이루어졌음을 알 수 있습니다. 무슨 말인지 모르겠나요? 각 요소에 대해 좀 더 알아볼게요.

 

 

프론트엔드 개발자가 만나는 에러 유형

<출처: 작가>

 

프론트엔드 개발에서 발생하는 대표적인 에러 유형은 다음과 같습니다.

 

1) JavaScript 오류

  • ReferenceError: 존재하지 않는 변수를 참조할 때 발생
  • TypeError: 잘못된 데이터 타입을 다룰 때 발생
  • SyntaxError: 문법 오류로 인해 코드가 실행되지 않을 때 발생
  • RangeError: 호출 스택이 초과되거나 배열의 길이를 초과할 때 발생

 

2) 네트워크 오류

  • CORS 오류: 다른 도메인에서 데이터를 가져올 때 발생하는 보안 관련 오류
  • Failed to fetch: 네트워크 요청이 실패할 때 발생
  • Timeout Error: 요청이 일정 시간 내에 응답을 받지 못할 때 발생

 

3) 브라우저 관련 오류

  • DOM 요소 참조 오류: null 또는 undefined인 요소를 조작하려 할 때 발생
  • CSS 관련 문제: 스타일이 예상대로 적용되지 않거나 레이아웃이 깨지는 경우
  • 렌더링 성능 문제: UI가 느려지거나 프레임 드롭이 발생하는 경우

 

이처럼 에러 메시지에 나오는 유형에 대한 이해만 있어도, 에러가 왜 발생했는지 알 수 있습니다. 이를 통해 우리가 만든 프로그램에서 어떤 부분에 집중해야 하는지 판단할 수 있게 됩니다.

 

 

어디서 발생한 에러인가?

에러 유형을 보고 어디에 집중해야 하는지 알았다면, 이제 정확히 우리 코드 어디에서 에러가 발생했는지를 추적해야 합니다. 이때 필요한 것이 바로 스택 트레이스입니다.

 

1) 스택 트레이스의 기본 구조

스택 트레이스는 보통 다음과 같은 형식으로 표시됩니다.

 

TypeError: Cannot read properties of undefined (reading `name`)
    at Object.getUserName (app.js:10)
    at fetchUserData (app.js:25)
    at main (app.js:40)

 

위의 예시를 보면, main 함수에서 fetchUserData를 호출했고, 그 내부에서 getUserName을 호출하다가 에러가 발생했음을 알 수 있습니다. 이러한 구조를 활용하면 어떤 함수가 에러의 원인인지 추적할 수 있습니다.

 

2) 스택 트레이스를 활용한 디버깅 방법

  • 에러가 발생한 첫 번째 줄을 확인하세요. 가장 위에 표시된 에러 메시지를 읽고, 어떤 유형의 오류인지 확인합니다.
  • 스택의 흐름을 따라가세요. 첫 번째 호출에서 마지막 호출까지, 함수가 어떤 경로로 실행되었는지를 분석합니다.
  • 관련된 파일과 라인 번호를 체크하세요. 예를 들어,app.js:10에서 문제가 발생했다면 해당 파일의 10번째 줄을 확인하여 어떤 코드가 문제를 일으키는지 살펴보세요.
  • 브라우저 개발자 도구의 “Call Stack” 탭 활용하기. Chrome DevTools의 “Sources” 탭에서 브레이크포인트를 설정하고, “Call Stack”을 확인하면 스택 트레이스를 시각적으로 분석할 수 있습니다. 
  • 의심되는 변수를 콘솔에서 직접 확인하기.console.log()를 사용하여 특정 변수가 예상한 값을 가졌는지 점검합니다.

 

이때 스택 트레이스의 전체를 볼 필요는 없습니다. 가장 마지막 추적만으로도 에러가 발생한 위치를 쉽게 찾을 수 있기 때문이죠. 그러나 간혹 여러 에러 상황에서 좀 더 추적을 따라가야만 하는 에러도 있습니다. 예를 들어, 실제 에러가 getUserName에서 발생한 것이 아니라, fetchUserData가 getUserName을 호출하지 않아야 했는데 호출한 경우일 수도 있습니다. 이 경우 우리가 코드에서 수정해야 할 부분은 마지막 추적인 getUserName이 아닌 fetchUserData입니다.

 

 

에러를 해결해 봅시다

이제 우리는 어떤 유형의 에러가 어디에서 발생했는지를 알게 되었습니다. 이제 이 에러를 해결해 봅시다. 에러를 해결하기 위해서는 작성한 코드의 논리를 순차적으로 따라가면서, 우리가 생각했던 논리대로 프로그램의 동작이 일치하는지 분석해야 합니다. 이 과정을 “디버깅”이라고 합니다. 이 디버깅은 다양한 도구를 이용하면 더욱 효과적입니다.

 

브라우저 개발자 도구(DevTools)를 활용한 디버깅

프론트엔드 개발에서 가장 강력한 디버깅 도구는 ‘브라우저 개발자 도구(DevTools)’입니다. Chrome, Firefox, Edge 등의 브라우저에서 제공하는 개발자 도구를 활용하면, 보다 효과적으로 에러를 분석할 수 있습니다.

 

1. 콘솔(Console) 활용

console.log()console.warn()console.error()를 사용하여 실행 중인 코드의 상태를 확인할 수 있습니다.

 

2. 네트워크 패널(Network Tab) 활용

  • API 요청이 정상적으로 이루어지는지 확인
  • 요청/응답 데이터 및 HTTP 상태 코드 확인
  • CORS 정책 위반 여부 파악

 

3. 요소 검사(Elements Tab)

  • 특정 HTML 요소의 구조 확인
  • 적용된 CSS 규칙 확인 및 실시간 수정

 

4. 소스 패널(Sources Tab)에서 브레이크포인트 설정

  • 특정 코드 라인에서 실행을 멈추고 변숫값을 확인할 수 있음
  • Call Stack을 통해 함수 호출 순서 확인 가능

 

5. 브라우저 디버거 활용

  • 소스의 특정 위치에서 동작이 멈추게 breakpoint를 사용할 수 있음
  • 대부분 원본의 소스가 아닌 번들이 된 소스이므로 크게 도움이 되지 않아 잘 사용되지 않음

 

VSCode 디버거 활용하기

다음으로 Visual Studio Code(VSCode)의 디버깅 기능을 활용하면, 프론트엔드 개발에서 발생하는 문제를 더욱 효과적으로 해결할 수 있습니다.

 

  • Live Server: 개발 중인 웹 애플리케이션을 실시간으로 확인 가능
  • 브레이크포인트 설정: 특정 코드 실행을 중지하고 상태를 확인
  • Call Stack 분석: 함수 실행 흐름을 추적하여 문제 발생 원인 파악
  • Watch 변수: 특정 변수의 값이 어떻게 변경되는지 실시간으로 모니터링

 

 

마침내 에러를 해결했습니다

이렇게 디버깅을 통해 논리의 실패가 확인되었다면, 코드를 수정하여 에러를 해결할 수 있습니다. 그렇다면 에러를 해결하고 나면 끝일까요? 이제 에러를 해결하는 데서 그치지 않고, 같은 에러가 재발하지 않도록 예방해야 합니다. 에러를 수정한 후에는 수정한 코드가 의도한 대로 작동하는지 확인하는 과정이 필수적인데요. 단순히 에러 메시지가 사라졌다고 해서, 문제가 완전히 해결되었다고 판단해서는 안 됩니다.

 

1) 테스트 코드 작성

수정된 코드와 관련된 기능이 제대로 작동하는지 확인하기 위해 테스트 코드를 작성하고 시행해야 합니다. 수정한 부분만이 아니라 회귀 테스트를 통해 수정한 부분이 기존 기능에 부정적인 영향을 미치지 않았는지 확인합니다. 회귀 테스트는 에러 수정 후 전체 애플리케이션의 안정성을 확보하는 데 중요한 역할을 합니다.

 

2) 에러 로그 기록 및 문서화

에러는 결국 개발자가 발생시킨 것이기 때문에, 같은 에러가 반복될 수 있습니다. 따라서 같은 에러 발생 시 효과적인 해결을 위해 발생한 에러와 해결 과정을 기록해야 합니다. 유사한 에러가 재발생할 때 문제를 빠르게 해결할 수 있도록 도와줍니다.

 

  • 에러 로그 작성하기:어떤 에러가 발생했는지, 어떤 상황에서 발생했는지, 그리고 어떻게 해결했는지를 기록합니다. 이를 통해 문제 해결 과정을 체계적으로 관리할 수 있습니다.
  • 지식 공유와 팀 내 문서화하기:혼자서 해결한 문제라도 팀원들과 공유하여 같은 문제가 다시 발생할 때 빠르게 대응할 수 있도록 합니다. 위키, 내부 블로그, 또는 공유 문서를 활용해 기록하는 것이 좋습니다.

 

<출처: Flux AI, 작가 편집>

 

 

에러, 너무 두려워하지 마세요

프로그래밍에서 에러는 피할 수 없는 요소이며, 이를 통해 배우고 성장할 기회로 삼는 것이 중요합니다. 에러가 발생했을 때 에러 메시지와 스택 트레이스를 분석하면, 미처 놓친 부분이나 개선할 수 있는 점을 찾는 과정에서 문제 해결 능력이 향상됩니다. 때론 에러가 좌절감을 줄 수도 있지만, 경험이 쌓이면서 이러한 문제가 곧 개발 실력 향상의 발판이 됩니다. 여러분이 아는 훌륭한 개발자들도 비슷한 어려움을 겪었고요.

 

그리고 개발 과정에서 발생하는 에러는 단순한 문제 상황이 아니라, 더 나은 코드를 만들기 위한 중요한 신호입니다. 에러 메시지를 통해 문제의 원인을 파악하고, 스택 트레이스를 활용해 디버깅을 진행하며, 철저한 테스트를 통해 문제를 해결할 수 있습니다. 

 

또한 에러 로그를 기록하고 팀 내에서 지식을 공유함으로써, 비슷한 문제에 빠르게 대응할 수 있는 체계를 마련해 팀의 성장도 이끌어 낼 수 있죠. 에러는 개발자로서 성장하는 과정의 일부이며, 이를 효과적으로 관리하는 능력은 훌륭한 개발자가 되기 위한 필수 역량입니다. 그러니 에러를 두려워하지 말고, 오히려 개선과 학습의 기회로 삼아 보면 어떨까요?