코린이의 기록

[ES6] 예외와 에러처리 본문

javascript,HTML,CSS

[ES6] 예외와 에러처리

코린이예요 2019. 7. 30. 11:08
반응형

Error 객체

javascript에는 내장된 Error 객체가 있다. 

에러 인스턴스 만들기 (Error 인스턴스를 만드는 것만으로 아무일도 일어나지 않음)

const err = new Error();

예외처리 예제 : 이메일 유효성 검사

const email = "abc@gmail.com";
const email2 = "abcgmail.com";

const validatedEmail = validateEmail(email2);
 if(validatedEmail instanceof Error){
    console.error(`Error : ${validatedEmail.message}`);
}else {
    console.log(`Valid email : ${validatedEmail}`);
} 

function validateEmail(email){
    return email.match(/@/) ?
    email :
    new Error(`envalid email: ${email}`);
}

Result

 

try/catch와 예외처리

예외를 처리할때 try/...catch문을 사용한다. 위 예제에서 본 '이메일 주소에서 @가 없을 때 발생되는 에러'뿐만 아니라 문자열이 null이거나 문자열이 아닌 어떠한 값이 들어갔을 때 error 처리는 어떻게 해야할까? 프로그래머가 예상하지 못한 상황에 대한 error를 처리할때 사용하는것이 try/...catch 문이다. 

위 예제에서 email 객체에 null값을 넣어서 테스트해보자.

const email = null;

Result

여기서 문제는 프로그래머가 예상치 못한 error가 발생했을때 프로그램이 멈춰버리고 더이상 진행되지 않는다. 이때 try/...catch문으로 error를 '캐치'하면 프로그램이 멈추는것은 막을 수 있다. 

 

const email = "abc@gmail.com";
const email2 = "abcgmail.com";
const email3 = null;

try {
    const validatedEmail = validateEmail(email3);
    if (validatedEmail instanceof Error) {
        console.error(`Error : ${validatedEmail.message}`);
    } else {
        console.log(`Valid email : ${validatedEmail}`);
    }
} catch (err) {
    console.error(`Error : ${err.message}`);
}

function validateEmail(email) {
    return email.match(/@/) ?
        email :
        new Error(`envalid email: ${email}`);
}

validateEmail 함수에서 사용되는 string method인 'match'를 호출하려고 할 때 javascript에서는 error를 캐치한다. 에러가 발생하면 바로 즉시 catch 문으로 이동한다. 따라서 try문에 있는 if문은 수행되지 않는다. 반대로 예외적인 error가 발생하지 않으면 catch문도 수행되지 않는다. 

 

Error 발생시키기

javascript가 error를 일으키는것말고 직접 error를 발생시킬 수 있다. (throw , raise)

현금 인출 기능을 예로들어보자. 잔고보다 인출하려고 하는 금액이 더 많으면 error 를 발생시키는 예제이다.

var account = {balance : 3000};
var amount = 10000;
var payee = "Gildong-Hong";
billPay(amount, payee, account)

function billPay(amount, payee, account) {
    if (amount > account.balance)
        throw new Error("잔고 부족");
    account.transfer(payee, amount);
}

잔고가 부족하므로 현금 인출단계인 account.transfer를 수행하지 않고 예외를 발생시킨다.

Result

 

예외 처리와 호출 스택

함수 a, b, c가 있다고 가정하자.

a함수가 b를 호출

b함수가 c를 호출

c가 실행을 마치면 실행흐름은 b로 돌아가고

b가 실행을 마치면 실행흐름은 a로 돌아간다. 

 

c가 실행하는동안 a와 b 함수는 완료되지 않는데, 이렇게 완료되지 않은 함수를 호출 스택이라고 부른다. (call stack)

 

error와 관련지어서 이야기해보면, c에서 에러가 발생하면 b와 a 함수에서도 에러가 발생하게 된다. 즉 error는 호출 스택을 따라 올라가게 된다. 

function a() {
    console.log('a : calling b' );
    b();
    console.log('a: done');
}

function b() {
    console.log ('b : calling c');
    c();
}

function c() {
    console.log ('c : throwing error');
    throw new Error('c Error');
    console.log('c : done');
}

function d() {
    console.log('d : calling c');
    c();
    console.log('d : done');
}

try {
    a();
}catch(err){
    console.error(err.stack);
}

try{
    d();
}catch(err){
    console.error(err.stack);
}

Result

여기서 at(@) 'function'로 스택 추적을 나타내준다. c는 b가, b는 a가 호출해준다는것을 보여준다. 별도로 c를 단독으로 호출하는 d에서도 c를 호출한것을 나타내준다. 

참고

visual code에서는 function c에서 'c : done'을 출력하는 부분이 흐리게 표시된다. 마우스를 갖다대보니 'Unreachable code detected'라고 친절하게 알려준다. 신기....

 

try...catch...finally

javascript에서 자원을 쓰고 해제하는 일을 처리할때 유용하게 사용되는것이 finally이다. http연결이나 file과 같은 resource를 사용해야 한다면 반드시 이 resource를 해제해주어야 하는데 try와 catch 구문에서는 error가 발생하였거나 발생하지 않았을때 수행되지 않을 수도 있으므로 안전하지 않다.  finally는 error가 발생하였든 안하였든 수행되는 블록이다.

Error 발생 할 때

try {
    console.log("this line is executed ..." );
    throw new Error ("throwing error");
    console.log("this line is not executed ...");
}catch (err){
    console.log(`there was an error, ${err.message}`);
}finally {
    console.log("...always executed");
    console.log("perform cleanup resource here ");
}

Result

Error가 발생하지 않을 때

try {
    console.log("this line is executed ..." );
}catch (err){
    console.log(`there was an error, ${err.message}`);
}finally {
    console.log("...always executed");
    console.log("perform cleanup resource here ");
}

Error가 발생하든 안하든 finally 블록이 수행된것을 확인할 수 있다. 이 블록에서 resource를 해제하면 안전하게 해제할 수 있다.

 

 

 

 

 

Reference : Learning Javascript (이선 브라운 지음)

반응형
Comments