로그인 페이지에서 아이디나 비밀번호를 잘 못 입력하는 경우 "아이디 또는 비밀번호를 확인해주세요" 와 같은 문구를 확인한 적이 있을 것입니다.
이렇게 특정 코드를 실행 시 에러가 발생되는 경우 에러 이후의 나머지 코드를 계속 실행하는 것은 의미가 없기에 일부러 예외를 만들어 에러를 발생시킬 수 있습니다. 이러한 방식을 예외처리라고 합니다.
이러한 예외처리는 try catch
, throat
을 활용해 만들 수 있으며, 커스텀 에러를 만들어 에러를 확장할 수도 있습니다.
오늘은 이 예외처리에 대해 공부한 내용을 정리해보려고 합니다.
TCP School에 설명되어 있는 내용에 따르면, 예외란 프로그램이 실행 중에 발생하는 런타임 오류(문법적인 오류)를 의미합니다.
기본적으로 에러를 다룰 때 쓰는 구문은 try catch입니다.
try {
} catch (e) {
//try 에서 에러 발생할 경우 실행되는 구문
}
try구문에서 발생된 에러는 e객체로 들어오며, 에러발생 시 실행될 구문을 catch구문에 넣을 수 있습니다.
존재하지 않는 함수를 실행시켜 에러를 발생시켜보록 하겠습니다.
try {
x()
} catch (e) {
//try 에서 에러 발생할 경우 실행되는 구문
console.error('에러 발생')
} finally {
// 어떠한 상황에서도 실행
}
실행 결과 콘솔에 "에러 발생" 이 표시가 되었습니다. 여기서 e는 에러 객체입니다. 이 error객체를 통해 어떤 에러가 났는지 에러꾸러미로 들어온다고 보면 되겠습니다. 위 예시에서는 e에 [ReferenceError: x is not defined]라는 에러에 대한 정보가 들어와 구문을 실행할 수 있습니다.
결론적으로 try catch문을 통해서 에러를 잡아내고 에러가 발생했을 때의 로직을 실행시킬수 있겠습니다.
앞서 살펴보았듯이 일부러 에러를 만들어 메세지를 사용자에게 보여줄 수 있습니다. 이 행위를 직접 작성해보도록 하겠습니다.
function login(id, pw) {
if (id === 'zero' && pw === 0000) {
return true;
}
}
try {
login('one', 111);
} catch (error) {
console.error(e);
console.error('에러발생');
} finally {
}
실행을 시켜보면 성공을 하지 못했음에도 아무런 에러를 내뱉지 못하고 있는 것을 확인할 수 있습니다. 이는 문법적인 에러가 잡히지 않아 생기는 문제로 사용자가 throw를 이용해 에러를 직접 정의를 할 수 있습니다.
function login(id, pw) {
if (id === 'zero' && pw === 0000) {
return true;
}
throw new Error('로그인 실패');
}
try {
login('one', 111);
} catch (error) {
console.error(error);
console.error('에러발생');
} finally {
//console.log('로그인 시도 시간: ' + new Data())
}
실행결과 [Eroor: 로그인 실패] , 에러 발생이 콘솔창에 뜨게 됩니다.
throw new Error
가 error
객체로 들어가 콘솔 창에 이 에러가 로그인 실패가 잘 담겨 나타나게 되는 것입니다. 이렇게 사용자가 throw new Error
로 직접 에러를 정의를 해 새롭게 에러를 만들어냈습니다.
브라우저 위에서 사용자에게 안내를 하고 싶은 경우 아래와 같이 사용할 수도 있습니다.
...
catch (error) {
window.alert('에러발생'); // 사용자에게 노출
...
에러는 스택형태로 쌓여서 기록이 되게 됩니다. 이렇게 에러의 stack
객체에서 에러를 확인할 수 있습니다.
try {
x()
} catch (e) {
console.error(e.stack)
}
앞으로 프로그램이 거대해지고 요구사항이 심화되면서 에러객체를 조금 더 깊이 다뤄야하는 경우가 생깁니다. 에러 객체는 메세지, 스택, name, property 등 다양하게 다룰 수 있습니다.
이런 경우 class문법을 활용해 직접 커스텀에러를 만들 수 있습니다.
class LoginError extends Error {
constructor(message) {
super(message);
this.name = 'Login Error';
}
}
이 커스텀 에러를 사용해보도록 하겠습니다.
function login(id, password) {
if (id !== 'a') {
throw new LoginError('아이디 불일치');
}
if (id === 'a' && password === 'a') {
return true;
}
}