본문 바로가기
언어/Javascript, Typescript

[js] try...catch, finally 정리

by minhyeok.lee 2023. 3. 23.
반응형

try...catch문, finally 블록 정리

1. try...catch문이란?

 실행할 코드블럭을 표시하고 예외(exception)가 발생(throw)할 경우의 응답을 지정한다.

try {
  // 수행하고싶은 로직을 수행한다.
  doSomething();
} catch (error) {
  console.error(error);
}

위 코드에서 doSomething() 부분에서 error 발생시 console에 error가 출력된다.

 

2. try...catch문 문법

try {
  try_statements
}
[catch (exception_var) {
  catch_statements
}]
[finally {
  finally_statements
}]

try_statements: try 블록에서 실행될 선언들이다.
catch_statements: try 블록에서 예외가 발생했을 때 실행될 선언들이다.
exception_var: catch 블록과 관련된 예외 객체를 담기 위한 식별자이다.
finally_statements: try 선언이 완료된 이후에 실행될 선언들이고 예외 발생 여부와 상관없이 무조건 실행된다.


3. try..catch문의 구성

 1. try 선언의 구성은 하나 혹은 그 이상의 선언을 포함한 try 블록 및 catch 항목이나 finally 항목 중 최소한 하나 혹은 둘 다 포함하여 이루어진다. 

 2. 즉, try 선언에는 세 가지 형식이 존재한다.
  2-1) try...catch
  2-2) try...finally
  2-3) try...catch...finally
 3. catch 블록은 try 블록 안에서 예외가 발생(throw)하는 경우 무엇을 할지 명시하는 코드를 포함한다.

 4. try 블록 (또는 try 블록 내에서 호출된 함수) 내의 명령문이 예외를 throw 하면 제어가 catch 블록으로 이동한다.

 5. try 블록에 예외가 발생하지 않으면 catch 블록을 건너뛴다.
 6. finally 블록은 try 블록과 catch 블록(들)이 실행을 마친 후, 예외가 발생했는지에 관계없이 항상 실행된다.
 7. 하나 이상의 try 문을 중첩 할 수 있다. 내부의 try 문에 catch 블록이 없으면, 둘러싼 try 문의 catch 블록이 입력된다.
 8. try 문을 사용하여 예외처리를 한다.

4.try...catch문

 

 4-1) 무조건적 catch 문

try {
   throw "myException"; // 예외를 생성한다.
}
catch (e) {
   // 예외를 처리하기 위한 상태이다.
   logMyErrors(e); // 오류 처리기에 예외 개체를 전달한다.
}

try-block 내에서 예외가 발생하면 catch-block이 실행된다.

예를 들어, 다음 코드에서 예외가 발생하면 제어가 catch 블록으로 전송된다.

 

4-2) 조건적 catch 문
 다음과 같이 try...catch블록을 if...else if...else 구조와 결합하여 조건부 catch-blocks을 만들 수 있다.

try {
  myroutine(); // 세 가지 유형의 예외를 발생한다.
} catch (e) {
  if (e instanceof TypeError) {
    // TypeError 예외를 처리하기 위한 구문이다.
  } else if (e instanceof RangeError) {
    // RangeError 예외를 처리하기 위한 구문이다.
  } else if (e instanceof EvalError) {
    // EvalError 예외를 처리하기 위한 구문이다.
  } else {
    // 지정되지 않은 예외를 처리하기 위한 상태이다.
    logMyErrors(e); // 오류 처리기에 예외 개체를 전달한다.
  }
}

 

이에 대한 일반적인 사용 사례는 예상 오류의 작은 하위 집합 만 포착(및 침묵)한 다음 다른 경우에 오류를 다시 발생시킨다.

try {
  myRoutine();
} catch (e) {
  if (e instanceof RangeError) {
    // 일반적인 예상 오류를 처리하기 위한 상태이다.
  } else {
    throw e;  // 오류를 수정하지 않고 다시 반환한다.
  }
}

 

예외 식별자 ( e )

 1. exception_var를 의미하고 catch (e) 내부의 e를 뜻한다.

 2. try-block에서 예외가 발생하면 e가 예외 값을 보유한다.

 3. 이 식별자를 사용하여 발생한 예외에 대한 정보를 얻을 수 있다.

 4. 이 식별자는 catch-block의 scope에서만 사용할 수 있다.

 

 

5. finally 블록

 1. finally 블록에는 try 블록과 catch 블록이 실행된 후 실행할 명령문이 포함되어 있다.

 2. finally 블록은 예외 발생 여부에 관계없이 실행된다.

 3. 예외가 발생하면 예외를 처리하는 catch 블록이 없어도 finally 블록의 명령문이 실행된다.

 4. 선언된 위치에서 무조건 실행된다고 생각하면 편하다.

 

다음 예는 finally 블록에 대한 한 가지 사용 사례를 보여준다.

openMyFile();
try {
  // 자원을 묶어둔다.
  writeMyFile(theData);
}
finally {
  closeMyFile(); // 항상 파일을 닫는다.
}

이 코드는 파일을 연 다음 파일을 사용하는 명령문을 실행한다.

finally 블록은 예외가 발생하더라도 파일이 사용된 후 항상 파일을 닫도록 한다.

 

중첩된 try 블록

try {
  try {
    throw new Error('oops');
  }
  finally {
    console.log('finally');
  }
}
catch (ex) {
  console.error('outer', ex.message);
}

출력값

"finally"
"outer" "oops"

 

이제 catch 블록을 추가하여 내부 try 블록에서 이미 예외를 포착한다면 외부 catch 블록은 동작하지 않는다.

try {
  try {
    throw new Error('oops');
  }
  catch (ex) {
    console.error('inner', ex.message);
  }
  finally {
    console.log('finally');
  }
}
catch (ex) {
  console.error('outer', ex.message);
}

출력값

"inner" "oops"
"finally"

 

내부 catch블록에서 오류를 다시 발생시키는 예제이다.

try {
  try {
    throw new Error('oops');
  }
  catch (ex) {
    console.error('inner', ex.message);
    throw ex;
  }
  finally {
    console.log('finally');
  }
}
catch (ex) {
  console.error('outer', ex.message);
}

출력값

"inner" "oops"
"finally"
"outer" "oops"

주어진 예외는 다시 발생하지 않는 한 가장 가까운 catch-block에 의해 한 번만 catch 된다.

"내부" 블록에서 발생하는 새로운 예외는 "외부" 블록에서 포착된다.

  - ex. 내부 catch 블록의 코드가 던지는 무언가가 새로운 예외일 경우가 있다.

 

 

finally 블록에서 반환

finally 블록이 값을 반환하면 이 값은 try 및 catch 블록의 반환 문에 관계없이 전체 try...catch...finally 문의 반환 값이 된다.

(function() {
  try {
    try {
      throw new Error('oops');
    }
    catch (ex) {
      console.error('inner', ex.message);
      throw ex;
    }
    finally {
      console.log('finally');
      return;
    }
  }
  catch (ex) {
    console.error('outer', ex.message);
  }
})();

위 코드는 catch 블록 내부에서 발생한 예외가 포함된다.

 

출력값

"inner" "oops"
"finally"

1. "outer" "oops"는 finally 블록의 return때문에 발생하지 않는다.

2. try...catch 블록에서 return된 모든 값에 동일하게 적용된다.

반응형

댓글