프로젝트를 할 때 나오는 에러의 경우다.
1. 내부 서버 에러 (클라이언트에 에러 메시지가 그대로 보여지면 안 됨)
2. 비즈니스 에러 (명백하게 에러는 아니지만, 경우에 따라 에러를 반환해야 하는 것)
1. 내부 서버 에러 (5XX)
내부 서버 에러는 우리가 코드 작성을 잘못해서 생기는 에러다.
혹은 서버에 사용자가 많이 몰려서 트래픽이 과부하되거나 통신 시간이 지연되었을 때 생긴다.
어떤 에러이든 간에 서버 내부의 에러가 직접적으로 사용자에게 보여지는 것은 위험한데,
이것을 처리하는 것은 굉장히 까다로워 보인다.
내부 서버 에러에 대한 예시는 다음과 같다.
const products = await Product.find({ _id: { $in: arrOfId } });
mongoose.Model
의 find
함수를 사용해서 데이터를 찾을 때,
findById
를 하던 도중 생기는 에러 (예를 들어, $in 연산자 사용 시엔 배열을 사용하지 않으면 에러가 난다.) 가 있다.
혹은 단순하게
const { Product } = require("../models/index");
const products = await Products.find({ _id: { $in: arrOfId } });
Product로 모델 값을 받아왔는데, Products라고 명시하면 find함수에 접근할 수 없다는 에러가 뜰 것이다.
이런 경우 생기는 에러를 그대로 클라이언트에 노출하지 말고,
try ~ catch
문으로 에러를 잡아 새로운 에러 메시지와 함께 클라이언트에 보내주는 코드를 작성해야 한다.
async getProductsById(arrOfId) {
const products =
await Product.find({ _id: { $in: arrOfId } })
.catch((error) => {
const error = new Error("서버 에러");
error.status = 500;
throw error; //던져진 에러는 서비스를 호출한 라우터에서 처리한다.
});
if (products.length === 0) {
const error = new Error("찾으려는 물품이 존재하지 않습니다.");
error.status = 404;
throw error; //던져진 에러는 서비스를 호출한 라우터에서 처리한다.
} else {
return products;
}
}
이렇게 find함수 실행을 하고 에러가 발생할 때 새로운 Error
객체와 status를 정의 후 라우터로 넘겨준다.
그리고 라우터에선 next(error)를 사용해 에러 처리 라우터로 에러를 넘겨주고,
에러 처리 라우터에서 해당 에러를 사용자에게 전송하거나 경우에 따라 다른 처리를 해준다.
2. 비즈니스 에러
비즈니스 에러는 위의 코드에서도 봤지만, find 함수로 얻은 데이터(배열)에 아무 값도 들어가 있지 않을 때,
length가 0인 것 자체는 시스템 상에서 에러가 아니지만, 경우에 따라 에러로 처리해야 하는 경우가 있을 것이다.
//...위의 코드와 동일
if (products.length === 0) {
const error = new Error("찾으려는 물품이 존재하지 않습니다.");
error.status = 404;
throw error; //던져진 에러는 서비스를 호출한 라우터에서 처리한다.
} else {
return products;
}
해당 정보의 경우 우리가 따로 Error
객체를 생성하지 않는다고 해서 문제가 될 건 없을 것이다.
다만 사용자가 어떤 product의 정보 페이지로 넘어가고자 하는데
넘겨준 product 데이터가 없어서 페이지에 아무것도 보여지지 않으면
사용자는 이 페이지가 데이터를 로드 중인 건지 데이터가 없는 것인지 알 수 없다.
그럴 때 경우에 따라 에러를 발생시켜 사용자에게 어떤 오류로 페이지가 제대로 보이지 않는지,
혹은 어떤 접근을 했을 때 접근이 거부 당한 경우에는 어떤 이유인지 알려주고자 할 때 쓸 수 있을 것이다.