본문 바로가기

Programing/Node.js

[JavaScript] Promise와 예외 핸들러...

어제 자바스크립트 관련 코드 리뷰를 하게 되다가 알게된 것 정리.

1. Promise로 구현된 함수를 await으로 호출 된 경우 reject가 된 경우 try ~ catch에 잡힌다.

2.Promise로 구현된 함수를 그냥 호출 한 경우 함수 내부에서 reject가 된 경우 try ~ catch에 잡히지 않는다.


무슨 소리지 할 케이스가 다분해서 예제를 적어본다.


await를 사용하여 호출

아래와 같이 foo와 boo 함수가 있고 제일 끝에 boo 호출한다.
var foo = req => new Promise((resolve, reject) => {
console.log('req: ' + req);
reject(new Error('wow'));
});

async function boo(req, res) {
try {
console.log('before');
const reservationInfo = await foo(req);
console.log('end');
} catch(error) {
console.log('this');
}
};

boo('request');


결과는 아래와 같다.

before

req: request

this


await를 사용하지 않고 호출

아래와 같이 await를 빼고 호출하면 Promise 로 구현된 함수가 바로 반환을 해버리기 때문에 예외를 잡을 수 없다.

var foo = req => new Promise((resolve, reject) => {
console.log('req: ' + req);
reject(new Error('wow'));
});

async function boo(req, res) {
try {
console.log('before');
const reservationInfo = foo(req); // await이 빠졌다.
console.log('end');
} catch(error) {
console.log('this');
}
};

boo('request');


before

req: request

end

(node:20821) UnhandledPromiseRejectionWarning: Error: wow

    at Promise (/Users/namo/a.js:4:10)

    at new Promise (<anonymous>)

    at foo (/Users/namo/a.js:1:80)

    at boo (/Users/namo/a.js:10:29)

    at Object.<anonymous> (/Users/namo/a.js:23:1)

    at Module._compile (internal/modules/cjs/loader.js:722:30)

    at Object.Module._extensions..js (internal/modules/cjs/loader.js:733:10)

    at Module.load (internal/modules/cjs/loader.js:620:32)

    at tryModuleLoad (internal/modules/cjs/loader.js:560:12)

    at Function.Module._load (internal/modules/cjs/loader.js:552:3)

(node:20821) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)

(node:20821) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.


이 경우에는 catch 핸들러를 달아주면 뭔가를 처리할 수 있다.

var foo = req => new Promise((resolve, reject) => {
console.log('req: ' + req);
reject(new Error('wow'));
});

async function boo(req, res) {
try {
console.log('before');
const reservationInfo = foo(req).catch( // handler 추가
function (error) {
console.log('catch handler');
});
console.log('end');
} catch (error) {
console.log('this');
}]
};

boo('request');



정말 기본적인 것인데 실무에서 실수하는 경우가 있다는 것을 알고 블로그에 정리해두었다.