장고 프레임워크의 경우에는 raise Exception만 하면 알아서 오류코드를 넘겨줬었다.
근데 express는 그런 공통 에러처리가 없어서 controller단에서 전부 오류를 처리해줘야하는 문제가 있었다.
이런식으로 모든 오류에 대해 catch한다음 status와 메시지를 전부 따로따로 처리해줘야 한다.
이런 경우, 두 가지 문제가 생긴다.
1. 예상치 못한 경우, 에러처리를 해줄 수 없다. => 이런 경우, 처리됐다고 response는 전송되지만 제대로 적용되지 않는 문제가 발생할 수 있음
2. res.status(상태코드).json(어쩌구...)하기 너무 귀찮음...
공통 에러 처리하기
https://expressjs.com/ko/guide/error-handling.html
위 링크에 따라 미들웨어로 이런 문제를 해결할 수 있다.
//errorHandler.ts
export default function errorHandler(callback) {
return (req, res, next) => {
callback(req, res, next).catch(next);
};
}
에러핸들러에 콜백함수 형태로 컨트롤러 함수를 받아서 실행될 수 있도록 에러 핸들러 미들웨어를 만들어주자.
이 에러 핸들러가 모든 컨트롤러에서 작동할 수 있도록 아래와 같이 router세팅부분에서 컨트롤러 함수를 감싸준다.
이러면 controller함수에서 error가 throw 되면 catch하여 next 함수로 넘겨버린다.
// app.ts
app.listen(port, () => {
console.log(`(●'◡'●) Friending Server (●'◡'●)`);
});
app.use((req, res, next) => {
res.status(404).send('404 Not Found ( •̀ ω •́ )');
});
app.use((err, req, res, next) => {
res.status(err.status || 500).json({ message: err.message });
});
해당 요청에 해당하는 url이 없는 경우, 에러는 없으므로 app.use((req, res, next)=>{})에 잡히게 된다.
고러면 404가 나간다.
만약 err 가 throw된 상태에서 catch되지 않았다면, 마지막 코드에 걸리게 되어 err.status가 없는 경우, 상태코드 500이 나가게 된다.
오 근데 Error객체에는 status라는게 없는데요?
export default class ErrorStatus extends Error {
status;
constructor(message: string, status: ErrorCode) {
super(message);
this.status = status;
}
}
그래서 Error클래스를 상속해서 ErrorStatus라는 커스텀 에러 클래스를 만들어줬다.
만약 특정 경우에 특정 상태코드의 에러를 만들고 싶다면 이렇게 해주면 된다.