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
에러 상세 내용을 담고 있는 문자 메시지
표준은 아니지만, name
과 message
이외에 대부분의 호스트 환경에서 지원하는 프로퍼티도 있습니다.
stack
은 가장 널리 사용되는 비표준 프로퍼티 중 하나입니다.
stack
현재 호출 스택. 에러를 유발한 중첩 호출들의 순서 정보를 가진 문자열로 디버깅 목적으로 사용됩니다.
선택적 catch 바인딩
💡 최근에 추가됨
스펙에 추가된 지 얼마 안 된 문법입니다. 구식 브라우저는 폴리필이 필요합니다.
에러에 대한 자세한 정보가 필요하지 않으면, catch
에서 이를 생략할 수 있습니다.
throw 연산자
throw 연산자는 에러를 생성합니다.
throw <error object>
이론적으로는 숫자, 문자열 같은 원시형 자료를 포함한 어떤 것이든 에러 객체(error object)로 사용할 수 있습니다. 하지만 내장 에러와의 호환을 위해 되도록 에러 객체에 name
과 message
프로퍼티를 넣어주는 것을 권장합니다.
자바스크립트는 Error
, SyntaxError
, ReferenceError
, TypeError
등의 표준 에러 객체 관련 생성자를 지원합니다. 이 생성자들을 이용해 에러 객체를 만들 수도 있습니다.
에러를 생성할 때 위 코드와 같이 원하는 메시지를 입력할 수 있습니다.
아래는 throw 예시입니다.
throw
연산자는 message
를 이용해 SyntaxError
를 생성합니다. 에러 생성 방식은 자바스크립트가 자체적으로 에러를 생성하는 방식과 동일합니다.
에러가 발생했으므로 try
의 실행은 즉시 중단되고 제어 흐름이 catch
로 넘어간 것을 얼럿 창을 통해 확인할 수 있습니다.
에러 다시 던지기
위 코드와 같이 예상했던 에러가 아닌 다른 예기치 않은 에러가 발생할 수 있습니다. 여기서 기존 에러만으로 정의하게 된다면 에러 발생 위치 또는 원인을 혼동하게 될 수 있습니다. 이렇게 에러 종류와 관계없이 동일한 방식으로 에러처리를 하는 것은 디버깅을 어렵게 하니 좋지 않습니다. 이런 문제를 피하고자 ‘다시 던지기(rethrowing)’ 기술을 사용합니다.
규칙은 간단합니다.
- catch가 모든 에러를 받습니다.
catch(err) {...}
블록 안에서 에러 객체err
를 분석합니다.- 에러 처리 방법을 알지 못하면
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
최근댓글