try...catch를 이용한 에러 핸들링

기록맨·2020년 12월 3일
4

JavaScript

목록 보기
1/1
post-thumbnail

자바스크립트에서 에러가 발생하면 코드는 멈추게 되고, 콘솔에 에러가 출력된다. 하지만 try...catch 문법을 사용하면 스크립트가 죽는 것을 방지하고, 에러 상황을 잡아 예외처리를 할 수 있게 한다. 기본적인 형태는 두 블록으로 구성되며 예시 코드는 아래와 같다.

기본 형태

try {

  // 이 구간에서 에러가 발생하면 catch로 이동

} catch (err) {

  // 에러 핸들링

}
  • 먼저 try 블록의 코드가 실행된다.
  • try 블록 안에 에러가 없다면 catch 블록은 건너 뛴다.
  • try 블록 안에서 에러 코드를 만나면 try 블록의 실행이 중단되고 catch 블록의 코드가 실행된다.
  • err 객체에는 에러에 대한 정보가 있다.

실제 작동 코드 살펴보자.

try {
  console.log("아직 에러 없음");

  a; // 에러 시작

  console.log("이곳은 실행 안됨");

} catch (err) {

  console.log(err); // a is not defined

  console.log("에러가 나도 이곳의 코드는 실행됨");

}

try 블록에서 에러가 나면 아래의 console.log()는 실행이 안되며 바로 catch 블록으로 넘어간다. err 객체가 콘솔창에 어떤 에러인지 표시해 주며, 에러가 발생해도 catch 블록의 코드는 계속 실행되는 것을 확인할 수 있다. 이 부분에 에러 예외 처리를 작성해 주면 된다.

try...catch는 런타임 에러에만 작동한다

try...catch는 실행이 가능한 코드에만 동작하며, 중괄호가 들어가는 등 자바스크립트 엔진이 해석할 수 없는 문법적 오류(SyntaxError)같은 경우는 작동하지 않는다.

try {
    
    {{ // SyntaxError

  console.log("자바스크립트 엔진은 이 코드를 이해할 수 없어 실행 자체가 안됨");

} catch (err) {

  console.log("여기도 실행 안됨");

}

try...catch는 동기적으로 동작한다

try...catchsetTimeout와 같이 비동기적으로 실행되는 코드의 에러는 잡아낼 수 없다.

try {
    
  setTimeout(() => {

    a; // 에러가 발생하지만 catch가 잡아낼 수 없음

  }, 1000);

} catch (err) {

  console.log("try 블록의 에러를 잡아낼 수 없음");

}

1초뒤 setTimeout의 익명함수가 실행되고 에러가 발생하지만 이미 자바스크립트 엔진은 try...catch 블록을 떠났기 때문에 오류를 잡아낼 수 없다. 비동기로 실행되는 코드의 에러를 잡으려면 반드시 해당 함수 안에서 try...catch 구문을 사용해야 한다.

setTimeout(() => {

  try {

    a; // 에러가 발생하지만 catch가 잡아낼 수 있음

  } catch (err) {

    console.log("try 블록의 에러를 잡아냄");

  }
  
}, 1000);

에러 객체

에러가 발생하면 자바스크립트는 에러 내용이 담긴 객체를 생성하고 catch 블록의 인수로 전달한다.

try {

  a; // 에러 시작

} catch (err) {

  console.log(err); // ReferenceError: a is not defined
  console.log(err.name); // ReferenceError
  console.log(err.message); // a is not defined
  
}

name 프로퍼티는 에러의 이름을 나타내고 message는 에러에 대한 상세 내용을 가지고 있다.

직접 에러를 생성해 던지기

throw 연산자

throw 연산자는 예외를 던질 수 있으며, catch 블록에 전달된다.

throw 연산자는 함수의 실행을 중단한다는 표현과 같다.

try {

  throw "예외 처리를 던짐";

  console.log("여긴 실행 안됨");

} catch (err) {

  console.log(err); // 예외 처리를 던짐
  
}

위 코드에서 throw는 예외를 던지고 있으며, throw 아래의 로직은 실행이 안된다. throw 연산자자와 에러 객체 생성자를 이용하여 예외 처리를 해보자.

에러 객체 생성자

const error = new Error("에러 발생");
const syntaxError = new SyntaxError("문법 에러 발생");

console.log(error); // Error: 에러 발생
console.log(syntaxError); // SyntaxError: 문법 에러 발생

자바스크립트는 Error, SyntaxError, ReferenceError, TypeError 등 표준 애러 객체 생성자를 지원하며, 이 생성자들을 이용해 에러 객체를 만들 수 있다.

생성한 에러 던지기

const person = {
  name: "foo",
  age: 20,
};

try {

  if (!person.gender) {
    throw new SyntaxError("성별이 없음");
  }

  console.log("이곳은 실행이 안됨"); // person.gender 값이 없기 때문에 실행이 안됨

} catch (err) {

  console.log(err); // Error: 성별이 없음
  
}

위 코드의 try 블록에서는 성별 값이 있는지 체크하고 있는데, 체크 대상인 person 객체에는 이름과 나이만 있고 성별이 없다. 때문에 성별이 없을 때 직접 생성한 에러를 던지고 있고, catch 블록에서 에러를 받아 출력하고 있다.

참고로 위 에러는 직접 생성한 에러이기 때문에 실제 SyntaxError 에러는 아니다.

에러 다시 던지기

try...catch는 애초에 try 블록에서 발생한 모든 에러를 잡는 목적으로 만들어졌다. 에러의 종류와 상관 없이 모든 에러를 잡는것은 디버깅에 어려움을 주기 때문에 예상치 못한 에러를 다시 던져서 에러의 종류에 따라 대응을 해줘야 한다.

const person = {
  name: "foo",
  age: 20,
};

const getError = () => {
  try {
    if (!person.gender) {
      throw new SyntaxError("성별이 없음");
      // throw new ReferenceError("성별이 없음");
    }
  } catch (err) {
    if (err instanceof SyntaxError) {
      console.log("이 에러는 " + err); // SyntaxError일 경우
    } else {
      throw err; // SyntaxError가 아닐 경우 밖으로 다시 던짐
    }
  }
};

try {
  getError();
} catch (err) {
  if (err instanceof ReferenceError) {
    console.log("이 에러는 " + err); // ReferenceError일 경우
  }
}

getError()가 실행되면서 SyntaxError를 잡아내고 있으며, 만약 SyntaxError 에러가 아닐 경우는 다시 에러를 함수 밖으로 던지며, 함수 외부에서 에러를 다시 잡고 있다. 함수 밖에서는 ReferenceError일 경우를 잡아내고 있다. SyntaxError일 경우는 함수 내부에서 에러를 잡고 ReferenceError일 경우는 함수 외부에서 잡는다고 보면 된다.

finally

finally절은 에러의 유무와 상관없이 마지막으로 사용되는 블록이며, 마지막 제어가 필요할 때 사용하면 된다.

try {
    
  throw new Error("에러 발생");

} catch (err) {

  console.log(err); // 에러 발생

} finally {

  console.log("항상 실행"); // 항상 실행

}

References

'try..catch'와 에러 핸들링
에러 처리를 어떻게 하면 좋을까? - 1
예외 ( throw,[try/catch/finally])

profile
반갑습니다람쥐

0개의 댓글