Javascript 문법중 하나인 try - catch에 대해서 알아보겠습니다 😉

try - catch는 에러 핸들링이 필요할 때 주로 사용합니다. 여기서 의문이 들 수 있겠죠! ‘왜 에러 핸들링을 해야 할까??’

단순하게 생각해보면 프로그램 실행시 에러가 발생하면 해당 프로그램은 종료되어 재실행을 하기 전까지 동작하지 않습니다. 이렇게 되면 프로그램을 사용하는 사용자 입장과 개발자 입장에서 곤란한 상황에 놓일 수 있습니다. 이때 try - catch를 사용하게 되면 프로그램이 종료되지 않고 해당 에러를 잡아 사용자 또는 개발자에게 해당 에러를 알려줄 수 있습니다. 즉, 예상 가능한 에러들과 예상치 못한 에러들을 개발자가 의도하여 보다 완성도 있는 프로그램을 만들어 낼 수 있습니다!

try - catch

try {

    // 코드 작성

} catch (error) {

    // 검출된 에러 핸들링

} finally {

    // 에러가 잡히든 잡히지 않든 무조건 실행될 코드 작성

}

위 코드는 Javascript 내에서 사용 가능한 try - catch - finally 문법입니다.

위 사진은 try - catch 알고리즘을 표현한 사진입니다.

에러가 없는 예시

에러가 발생한 예시

위 코드와 같이 중간에 에러가 발생하면 그 즉시 catch로 이동해 에러 핸들링이 시작됩니다. 그리고 에러가 발생해도 finally는 정상적으로 동작하는 것을 확인할 수 있습니다.

⚠️ try - catch는 런타임 에러에만 동작!

try - catch는 실행 가능한(runnable) 코드에만 동작합니다. 실행 가능한 코드는 유효한 자바스크립트 코드를 의미하며 위 코드와 같이 중괄호 짝이 안 맞는 것들 즉, 코드가 문법적으로 잘못된 경우엔 try - catch가 동작하지 않습니다.

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

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

⚠️ try - catch는 동기적으로 동작합니다.

setTimeout처럼 ‘스케줄(scheduled)’된 코드에서 발생한 예외는 try - catch에서 잡아낼 수 없습니다.

setTimeout에 넘겨진 익명 함수는 엔진이 try..catch를 떠난 다음에서야 실행되기 때문입니다.

스케줄 된 함수 내부의 예외를 잡으려면, try - catch를 반드시 함수 내부에 구현해야 합니다.

⚠️ 에러 객체

catch에서 잡아내는 error는 객체 형식입니다. 또한 e, err, error 대신 원하는 이름으로 작성할 수 있습니다.

내장 에러 전체와 에러 객체는 두 가지 주요 프로퍼티를 가집니다.

 

name

에러 이름.

정의되지 않은 변수 때문에 발생한 에러라면 "ReferenceError"가 이름이 됩니다.

 

message

에러 상세 내용을 담고 있는 문자 메시지

표준은 아니지만, namemessage 이외에 대부분의 호스트 환경에서 지원하는 프로퍼티도 있습니다.

 

stack은 가장 널리 사용되는 비표준 프로퍼티 중 하나입니다.

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

선택적 catch 바인딩

💡 최근에 추가됨

스펙에 추가된 지 얼마 안 된 문법입니다. 구식 브라우저는 폴리필이 필요합니다.

에러에 대한 자세한 정보가 필요하지 않으면, catch에서 이를 생략할 수 있습니다.

throw 연산자

throw 연산자는 에러를 생성합니다.

throw <error object>

이론적으로는 숫자, 문자열 같은 원시형 자료를 포함한 어떤 것이든 에러 객체(error object)로 사용할 수 있습니다. 하지만 내장 에러와의 호환을 위해 되도록 에러 객체에 namemessage 프로퍼티를 넣어주는 것을 권장합니다.

자바스크립트는 Error, SyntaxError, ReferenceError, TypeError등의 표준 에러 객체 관련 생성자를 지원합니다. 이 생성자들을 이용해 에러 객체를 만들 수도 있습니다.

에러를 생성할 때 위 코드와 같이 원하는 메시지를 입력할 수 있습니다.

아래는 throw 예시입니다.

throw 연산자는 message를 이용해 SyntaxError를 생성합니다. 에러 생성 방식은 자바스크립트가 자체적으로 에러를 생성하는 방식과 동일합니다.

에러가 발생했으므로 try의 실행은 즉시 중단되고 제어 흐름이 catch로 넘어간 것을 얼럿 창을 통해 확인할 수 있습니다.

에러 다시 던지기

위 코드와 같이 예상했던 에러가 아닌 다른 예기치 않은 에러가 발생할 수 있습니다. 여기서 기존 에러만으로 정의하게 된다면 에러 발생 위치 또는 원인을 혼동하게 될 수 있습니다. 이렇게 에러 종류와 관계없이 동일한 방식으로 에러처리를 하는 것은 디버깅을 어렵게 하니 좋지 않습니다. 이런 문제를 피하고자 ‘다시 던지기(rethrowing)’ 기술을 사용합니다.

규칙은 간단합니다.

  1. catch가 모든 에러를 받습니다.
  2. catch(err) {...} 블록 안에서 에러 객체 err를 분석합니다.
  3. 에러 처리 방법을 알지 못하면 throw err를 합니다.

정의되지 않은 변수에 접근하여 에러를 발생시킵니다.

err.name 프로퍼티로 에러 클래스 이름을 알 수도 있습니다. 기본형 에러는 모두 err.name 프로퍼티를 가집니다. 또는 err.constructor.name를 사용할 수도 있습니다.

에러를 다시 던져서 catch 블록에선 SyntaxError만 처리되도록 해보면,

catch 블록 안에 다시 던져진(rethrow) 에러는 try - catch 밖으로 던져집니다. 이때 바깥에 try - catch가 있다면 여기서 에러를 잡습니다. 아니라면 스크립트는 죽을 겁니다. 이렇게 하면 catch 블록에선 어떻게 다룰지 알고 있는 에러만 처리하고, 알 수 없는 에러는 건너뛸 수 있습니다.

이제 try - catch를 하나 더 만들어, 다시 던져진 예상치 못한 에러를 처리해 보겠습니다.

함수 내의 에러 발생은 SyntaxError만 처리할 수 있지만, 함수 바깥의 try..catch에서는 예상치 못한 에러도 처리할 수 있게 되었습니다.

💡 `try..catch..finally` 안의 변수는 지역 변수입니다.
위 예시에서 변수 `diff`와 `result`는 `try..catch` 전 에 선언되었다는 점에 주의해 주세요.
`try` 블록 안에서 선언한 변수는 블록 안에서만 유효한 지역 변수가 됩니다.
💡 `finally` 와 `return` `finally` 절은 `try..catch` 절을 빠져나가는 어떤 경우에도 실행됩니다.
`return`을 사용해 명시적으로 빠져나가려는 경우도 마찬가지입니다.
`try` 블록 안에 `return`이 있을 경우에 값이 바깥 코드로 반환되기 전에 `finally`가 실행됩니다.
💡 `try..finally` `catch` 절이 없는 `try..finally` 구문도 상황에 따라 유용하게 쓸 수 있습니다.
`try..finally` 안에선 에러를 처리하고 싶지 않지만, 시작한 프로세스가 마무리되었는지 확실히 하고 싶은 경우에 사용합니다.

⭐️ try - catch 요약

try..catch를 이용하면 런타임 에러를 처리할 수 있습니다. try에선 코드를 실행하고, 에러가 발생하면 catch에서 잡아냅니다.

try..catch, try..catch..finally이외에도 try..finally를 사용할 수 있습니다.

에러 객체엔 다음과 같은 프로퍼티가 있습니다.

  • message – 사람이 읽을 수 있는 형태의 에러 메시지
  • name – 에러 이름을 담은 문자열 (에러 생성자 이름)
  • stack – 표준이 아니지만 대부분의 호스트 환경이 지원하는 프로퍼티로 에러가 발생한 순간의 스택을 나타냄

에러 객체가 필요 없으면 catch(err) { 대신 catch {를 쓸 수 있습니다.

throw 연산자를 사용하면 에러를 직접 만들 수 있습니다. 이론상으론, throw 인수에 모든 것을 넘길 수 있지만, 대개 내장 Error 클래스를 상속받은 에러 객체를 인수에 넘깁니다. 에러 상속에 대해선 다음 챕터에서 다룰 예정입니다.

다시 던지기는 에러 처리 시 사용되는 중요한 패턴입니다. catch 블록에선 대개 예상하였거나 어떻게 다룰지 알고 있는 에러를 다루고, 예상치 못한 에러는 다시 던지기 합니다.

try..catch가 없어도 대부분의 호스트 환경이 ‘전역’ 에러 핸들러를 지원하기 때문에 ‘떨어져 나온’ 에러를 잡을 수 있습니다. window.onerror는 브라우저 환경의 전역 에러 핸들러입니다.

try - catch에 대해 알아봤습니다 😀

 

출처 : 'try..catch'와 에러 핸들링

 

'try..catch'와 에러 핸들링

 

ko.javascript.info

 

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기