오늘 다뤄볼 내용은 express에서의 error 처리입니다.
express는 비동기로 발생한 오류를 처리하지 못합니다. 이런 경우를 위해 next함수를 사용하지만 express는 이를 동기에서 오류와 같은 형태로 취급합니다.
app.get('/api', async(req, res) => {
throw new Error('BROKEN!');
})
이러한 코드를 작성하고 에러가 났다면, 콘솔에서는 `UnhandlePromiseRejectionWarning' 이라는 에러를 반환합니다. Promise rejection 핸들링 되지않았다는 오류입니다.
이런 경우에 express는 이런방법을 제시합니다.
app.get('/', function (req, res, next) {
Promise.resolve().then(function() {
throw new Error('error');
.catch(next)
})
})
app.get('/', async function (req, res, next) {
try {
throw new Error('error')
}
catch (err) {
next(err)
}
})
동작은 잘되지만 깔끔하지않습니다.
express는 라우팅 핸들러에서 오류가 발생한 경우에, ext 콜백함수에 error를 전달해서 마지막 에러 처리 미들웨어에서 받아서 처리할 수 있도록 하고 있습니다.
하지만 async-await 함수에서 발생한 오류는 일반 함수 내에서 try/catch로 잡을 수 없습니다.
이를 잡기 위해서는 async 함수 안에서 또 try/catch를 함으로 예외 처리가 가능합니다.
express-async-erros 패키지는 async/await의 에러를 깔끔하게 다룰 수 있게 도와줍니다.
const express = require('express');
require('express-async-errors');
const app = express();
app.get('/', async (req, res, next) => {
throw new Error('BROKEN');
});
app.listen(3000, () => {
console.info('test server is running!');
});
이렇게 하면 위에서 처럼 next함수를 호출해줄 필요가 없어집니다.
그럼에도 불구하고 에러가 발생할 수 있습니다. 그럴때 사용하는게 이 프로세스 객체에 이벤트 'uncaughtException'과 'unhandleRejection' 입니다.
process.on('unhandleRejection', (err, result) => {
err.message, err.code, err.stack
})
process.on('uncaughtException', (err, result) => {
err.message, err.code, err.stack
})
'uncaughtException' 는 예상치 못한 오류에 대한 적절한 처리를 위한 이벤트 입니다. 이는 프로세스가 종료되는 걸 막아줄 수 있습니다.
node.js는 uncaughtException 사용을 자제하도록 권장하고 있습니다. 에러가 발생할 경우에는 application 을 재시작하도록 합니다.
에러를 명확하게 확인 하기 위해서는 'error.message', 'error.code', 'error.stack'속성을 확인해봐야합니다.
https://teamdable.github.io/techblog/express-error-handling
https://yceffort.kr/2021/06/error-handling-in-nodejs
https://programmingsummaries.tistory.com/375
https://runebook.dev/ko/docs/node/process