개인공부/TIL(Today I Learned)

TIL 87일차_ try...catch문을 사용한 예외처리

soon327 2021. 4. 15. 20:41

오늘은 페어프로그래밍을 하면서
try catch문을 다시 알게되서, 꼭 정리를 해야겠다는 생각을 했다.

그동안 try catch문을 꽤 사용해왔지만
항상 비동기처리를 할때에만 써왔고,
다른경우의 예외처리는 늘 조건문을 통해서 처리해왔다.

그런데 오늘 페어분이 서버쪽 로직을 작성하는데 에러가나서 테스트가 넘어가지 않자,
try catch문을 사용해서 예외처리를 해주는 걸 보고 여쭤봤더니,
서버쪽 로직을 작성할 때 서버가 다운될 수 있는 경우에
try catch문을 빈번하게 사용한다고 말씀해 주셨다.

그말을 듣고 나의 우매함을 반성하며 try, catch, finally 문에 대해 정리해야겠다는 생각이 들었다.

try...catch와 에러핸들링

아무리 프로그래밍에 능한 사람이더라도 에러가 있는 스크립트를 작성할 수 있습니다.
원인은 아마도 실수, 예상치 못한 사용자 입력, 잘못된 서버 응답 등의 수천만 가지 이유 때문일 겁니다.
에러가 발생하면 스크립트는 ‘죽고’(즉시 중단되고), 콘솔에 에러가 출력됩니다.
그러나 try..catch 문법을 사용하면 스크립트가 죽는 걸 방지하고,
에러를 ‘잡아서(catch)’ 더 합당한 무언가를 할 수 있게 됩니다.
/Javascript.Info


try…catch 동작 알고리즘은 다음과 같습니다.

  1. 먼저, try {...} 안의 코드가 실행된다.
  2. 에러가 없다면, try 안의 마지막 줄까지 실행되고, catch 블록은 건너뜁니다.
  3. 에러가 있다면, try 안 코드의 실행이 중단되고, catch(err) 블록으로 제어 흐름이 넘어갑니다.
    변수 err(아무 이름이나 사용 가능)는 무슨 일이 일어났는지에 대한 설명이 담긴 에러 객체를 포함합니다.

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

try {
  {{{{{{{{{{{{
} catch(e) {
  alert("유효하지 않은 코드이기 때문에, 자바스크립트 엔진은 이 코드를 이해할 수 없습니다.");
}

자바스크립트 엔진은 코드를 읽고 난 후 코드를 실행한다.
코드를 읽는 중에 발생하는 에러는 'parse-time 에러’라고 부르는데,
엔진은 이 코드를 이해할 수 없기 때문에 parse-time 에러는 코드 안에서 복구가 불가능하다.

try..catch는 유효한 코드에서 발생하는 에러만 처리할 수 있다.
이런 에러를 ‘런타임 에러(runtime error)’ 혹은 '예외(exception)'라고 부른다.

catch의 인자 err는 뭘까?

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

try {
  // ...
} catch(err) { // <-- '에러 객체', err 대신 다른 이름으로도 쓸 수 있음
  // ...
}

만약 err내용이 필요없다면 그냥 인자없이 catch{}로 사용해도 된다.

catch에 전달된 내장 에러 전체와 에러 객체는 두 가지 주요 프로퍼티를 가진다.

name
에러 이름. 정의되지 않은 변수 때문에 발생한 에러라면 "ReferenceError"가 이름이 된다.
message
에러 상세 내용을 담고 있는 문자 메시지
stack
표준은 아니지만, name과 message 이외에 대부분의 호스트 환경에서 지원하는 프로퍼티도 있다.
stack은 가장 널리 사용되는 비표준 프로퍼티 중 하나이다.
현재 호출 스택. 에러를 유발한 중첩 호출들의 순서 정보를 가진 문자열로 디버깅 목적으로 사용된다.

예시

try {
  lalala; // 에러, 변수가 정의되지 않음!
} catch(err) {
  alert(err.name); // ReferenceError
  alert(err.message); // lalala is not defined
  alert(err.stack); // ReferenceError: lalala is not defined at ... (호출 스택)

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

try...catch 실사용

다음의 예시는
잘못된 형식의 json이 들어왔을 때, JSON.parse는 에러를 만들기 때문에 스크립트가 죽는 경우이다.

서버에서 전달받은 데이터가 잘못되어 스크립트가 죽는 경우,
사용자는 개발자 콘솔을 열지 않는이상 절대 원인을 알 수 없다.
이럴때, try...catch를 사용해 에러처리를 할 수 있다.

let json = "{ bad json }";

try {

  let user = JSON.parse(json); // <-- 여기서 에러가 발생하므로
  alert( user.name ); // 이 코드는 동작하지 않습니다.//////

} catch (e) {
  // 에러가 발생하면 제어 흐름이 catch 문으로 넘어옵니다.
  alert( "데이터에 에러가 있어 재요청을 시도합니다." );
  alert( e.name );
  alert( e.message );
}

throw연산자와 finally문에 대해서는 이어서 쓰도록 해야겠다!!


Reference
javascript.info