[JavaScript][TIL] 에러 처리의 필요성 / try...catch...finally문

Trippy·2023년 11월 16일
1

JavaScript

목록 보기
21/28
post-thumbnail

에러 처리의 필요성

에러가 발생하지 않는 코드를 작성하는 것은 불가능하다. 따라서 에러는 언제나 발생할 수 있다. 발생한 에러에 대해 대처하지 않고 방치하면 프로그램은 강제 종료된다.

console.log("[Start]");

foo(); // ReferenceError: foo is not defined
// 발생한 에러를 방치하면 프로그램이 강제 종료된다.

// 에러에 의해 프로그램이 강제 종료되어 아래 코드는 실행되지 않는다.
console.log("[End]")

try...catch문을 사용해 발생한 에러에 적절하게 대응하면 프로그램이 강제 종료되지 않고 계속해서 코드를 실행시킬 수 있다.

console.log("[Start]")

try {
  foo();
} catch (err) {
  console.log("[에러 발생]",err);
  // [에러 발생] ReferenceError: foo is not defined;
}

// 발생한 에러에 적절한 대응을 하면 프로그램이 강제 종료되지 않는다.
console.log("[END]")

직접절으로 에러를 발생하지는 않는 예외적인 상황이 발생할 수도 있다. 예외적인 상황에 적절하게 대응하지 않으면 에러로 이어질 가능성이 크다.

// DOM에 button 요소가 존재하지 않으면 querySelector 메서드는 에러를 발생시키지 않고 null을 반환한다.
const $button = document.querySelector('button'); // null

$button.classList.add('disabled');
// TypeError: Cannot read property 'classList' of null

위 예제의 querySelector 메서드는 인수로 문자열이 css 선택자 문법에 맞지 않는 경우 에러를 발생시킨다.

const #elem = document.querySelector('#1')
// DOMException: Failed to execute `querySelector`: '#1' is not a valid selector

하지만 querySelector 메서드는 인수로 전달한 css 선택자 DOM에서 요소 노드를 찾을 수 없는 경우 에러를 발생시키지 않고 null을 반환한다. 이때 if문으로 querySelector 메서드의 반환값을 확인하거나 단축 평가 또는 옵셔널 체이닝 연산자?.을 사용하지 않으면 다음 처리에서 에러로 이어질 가능성이 크다.

// // DOM에 button 요소가 존재하지 않으면 querySelector 메서드는 에러를 발생시키지 않고 null을 반환한다.
const $button = document.querySelector('button');

$button?.classList.add('disabled');

이처럼 에러나 예외적인 상황에 대응하지 않으면 프로그램은 강제 종료될 것이다. 에러나 예외적인 상황은 너무나 다양하기 때문에 아무런 조치 없이 프로그램이 강제 종료된다면 원인을 파악하여 대응하기 어렵다.

에러가 발생하지 않는 코드를 작성하는 것이 이상적이지만 안타깝게도 그것은 불가능하다. 따라서 우리가 작성한 코드에서는 언제나 에러나 예외적인 상황이 발생할 수 있다는 것을 전제하고 이에 대응하는 코드를 작성하는 것이 중요하다.


try..catch...finally문

기본적으로 에러 처리를 구현하는 방법은 크게 두 가지가 있다.

if문이나 단축 평가 또는 옵셔널 체이닝 연산자를 통해 확인해서 처리하는 방법과 에러 처리 코드를 미리 등록해 두고 에러가 발생하면 에러 처리 코드로 점프하는 방법이 있다.

try...catch...finally문은 두 번째 방법이다. 일반적으로 이 방법을 에러 처리라고 한다.
try...catch...finally문은 다음과 같이 3개의 코드 블록으로 구성된다. finally문은 불필요하다면 생략가능하다. catch문도 생략 가능하지만 catch 문이 없는 try문은 의미가 없으므로 생략하지 않는다.

try {
  // 실행할 코드(에러가 발생할 가능성이 있는 코드)
} catch {
  // try 코드 블록에서 에러가 발생하면 이 코드 블록의 코드가 실행된다.
  // err에는 try코드 블록에서 발생한 Error 객체가 전달된다.
} finally {
  // 에러 발생과 상관없이 무조건 한 번 실행된다
}
console.log('[Start]')

try{
  // 실행할 코드(에러가 발생할 가능성이 있는 코드)
  foo();
} catch(err) {
  // try 코드 블록에서 에러가 발생하면 이 코드 블록의 코드가 실행된다.
  // err에는 try코드 블록에서 발생한 Error객체가 전달된다.
  console.log(err);
} finally {
  // 에러 발생과 상관없이 반드시 한 번 실행된다.
  console.log("finally")
}
// try...catch...finally 문으로 에러를 처리하면 프로그램이 강제 종료되지 않는다.
console.log("[End]")
profile
감금 당하고 개발만 하고 싶어요

0개의 댓글