JavaScript

[JavaScript] try...catch 에러 핸들링

FRDYtheme 2022. 12. 28. 10:33

스크립트에 에러가 있을 경우 에러 발생 구문을 실행한 후 스크립트를 중단 없이 진행하는 구문.

 

스크립트는 에러가 있을 경우 그 즉시 실행을 멈추고 죽어버리는데 try..catch문을 사용하면 스크립트가 죽는 걸 방지할 수 있고

코드를 디버깅하기도 유용함.

 

단, 런타임 에러에만 동작하며 중괄호 짝이 안맞는 등 작성 방식이 잘못된 경우에는 동작하지 않음.

 

또 setTimeOut처럼 스케쥴 된 코드는 엔진이 try...catch 구문을 떠난 후에 실행되므로 작성한다면 setTimeOut 코드 내부에 try...catch문을 작성해야 한다. 

 

자바스크립트는 에러가 발생하면 에러 객체를 생성한다.

그 후 catch블록에 에러를 인수로 전달한다.

try {
 // 
} catch(err) { // 에러 객체로 err 대신 다른 이름 사용 가능.
 // 
}

 

내장 에러 전체와 에러 객체는 두 개의 주요 프로퍼티를 갖는다.

{

name: 에러 이름

message: 에러의 상세 내용을 담은 메시지

}

또, 표준은 아니지만 대부분의 호스트 환경에서 지원하는 프로퍼티도 있는데 대표적으로 stack(비표준 프로퍼티)이 있다.

stack: 현재 호출 스택. 에러를 유발한 중첩 호출들의 순서 정보를 가진 문자열. 디버깅 목적으로 사용 됨.

<script>
  try {
    정의되지않은변수;
  } catch (err) {
    console.log(err.name); // ReferenceError
    console.log(err.message); // lalala is not defined
    console.log(err.stack); // ReferenceError: lalala is not defined ar ... (호출 스택)

    // 에러 전체를 보여줄 수도 있다. 이때 에러 객체는 "name: message" 형태의 문자열로 반환.
    alert(err); // ReferenceError: lalala is not defined
  }
</script>

 

throw 연산자

throw 연산자는 에러를 생성하는데 숫자, 문자열 등 원시형 자료를 포함한 어떤 것이든 객체로 사용할 수 있다.

그러나 내장 에러 객체와의 호환을 위해 웬만하면 name과 message 프로퍼티를 포함하는 것을 권장.

throw <error object>

 

자바스크립트에는 표준 에러 객체를 생성할 수 있는 에러 생성자 함수가 있으며 이것을 이용해 에러를 생성할 수 있다.

이 경우 name 프로퍼티는 생성자 이름과 동일한 값을 가지며 message 프로퍼티는 인수에서 값을 받는다.

let error = new Error(message);
let error = new SyntaxError(message);
let error = new ReferenceError(message);

 

throw가 에러를 생성하는 건 자바스크립트가 에러를 생성하는 방식과 동일하며

직접 에러를 만들어 제어할 때 사용할 수 있다.

 

만약 객체 내의 프로퍼티를 찾지 못한 상황이 발생하면 값이 undefined로 반환될 뿐

try.. catch문을 사용해도 에러로 처리되지 않는다.

<script>
  try {
    const user = { id: 1, age: 30 };
    alert(user.name); //undefined
  } catch (err) {
    alert("사용자 이름을 찾을 수 없습니다!"); // 실행되지 않음.
  }
</script>

 

사용자의 입장에서 에러를 인지하기 어려운 상황이 발생할 수 있기 때문에 throw를 사용해 에러메시지를 던져줄 수 있다.

<script>
  try {
    const user = { id: 1, age: 30 };
    if(!user.name) { // user.name이 없으면 에러를 생성.
        throw new SyntaxError("사용자 이름을 찾을 수 없음")
    }
    alert(user.name); // user.name이 없기 때문에 에러로 취급하며 catch문으로 넘어감.
  } catch (err) {
    alert(err) // SyntaxError : 사용자 이름을 찾을 수 없음
  }
</script>

 

finally

try..catch문에는 finally라는 코드를 추가할 수 있는데 finally는 try..catch문의 마지막에 무조건 실행되는 구문.

 

함수는 return이나 throw를 만나면 바로 실행을 멈추는데 종료되지만try..catch문 내에서는  return이나 throw를 만나도 finally문이 있다면 무조건 실행되고 종료된다.