node.js에서 가장 많이 사용되는 오류를 처리하는 방식
1. 객체를 활용
■ 장점
- 오류 유형과 메세지를 빠르게 조회할 수 있음
- 중앙 집중식으로 오류 코드와 메세지를 관리할 수 있음
■ 단점
- 오류 유형이 추가될 때마다 객체를 업데이트 해야함
■ 사용 상황
- 오류 유형이 많지 않고, 특정한 오류 메세지나 코드에 대한 빠른 조회가 필요한 경우
■ 사용 방법
① 오류 정보를 담은 객체 만들기
1
2
3
4
5
6
7
8
9
10
| const errors = {
ER_BAD_FIELD_ERROR: {
code: StatusCodes.BAD_REQUEST,
message: "잘못된 필드를 참조"
},
ER_NO_SUCH_TABLE: {
code: StatusCodes.BAD_REQUEST,
message: "존재하지 않는 테이블을 참조"
}
};
|
② 객체를 사용하여 오류를 처리하기
1
2
3
4
5
6
7
8
9
| const handleError = (res, error) => {
console.error(error);
const message = errors[error.name]?.message || "내부 서버 오류";
const statusCode =
errors[error.name]?.code || StatusCodes.INTERNAL_SERVER_ERROR;
res.status(statusCode).send({ message });
};
|
2. switch문을 사용
■ 장점
■ 단점
- 코드가 길어질 수 있음
- 오류 유형이 많을수록 관리가 어려워짐
■ 사용 상황
- 오류 처리가 간단하고 명확한 조건 분기를 원할 때 사용
■ 사용 방법
① 오류 처리 함수 구현 (switch문 사용)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| function handleError(errorType, res) {
switch (errorType) {
case "ER_BAD_FIELD_ERROR":
res
.status(StatusCodes.BAD_REQUEST)
.send({ message: "잘못된 필드를 참조하였습니다." });
break;
case "ER_NO_SUCH_TABLE":
res
.status(StatusCodes.BAD_REQUEST)
.send({ message: "존재하지 않는 테이블을 참조하였습니다." });
break;
default:
res
.status(StatusCodes.INTERNAL_SERVER_ERROR)
.send({ message: "내부 서버 오류" });
}
}
|
3. 커스텀 에러 클래스 사용
■ 장점
- 각 오류 유형별로 명확한 클래스를 가짐 (직관적)
- 오류 유형에 따라 다른 처리 로직을 쉽게 구현할 수 있음
- 에러 인스턴스에 추가적인 정보를 포함시킬 수 있음
■ 단점
- 유형별로 클래스가 생기기때문에 많은 클래스를 생성하고 관리해야함
■ 사용 상황
- 대규모 애플리케이션에서 오류를 세분화하여 관리할 때
- 추가적인 에러 정보를 포함시켜야할 때
■ 사용 방법
① BadRequestError 클래스 정의
1
2
3
4
5
6
7
8
| class BadRequestError extends Error {
constructor(message) {
super(message);
this.statusCode = StatusCodes.BAD_REQUEST;
}
}
module.exports = { BadRequestError };
|
② 오류 생성
1
2
3
4
5
| const { BadRequestError } = require("./errors");
if (!bookId) {
throw new BadRequestError("잘못된 형식의 book id 값");
}
|
③ 에러 처리 미들웨어 등록하기
router 가장 마지막에 작성
1
2
3
4
5
6
7
8
| // app.js
const express = require("express");
const app = express();
// 여러개의 router
// 에러 처리 미들웨어 등록 및 사용
app.use(handleError);
|
④ 에러 처리 미들웨어에서 오류 처리하기
err, req, res, next
의 인자를 가짐
1
2
3
4
5
6
7
8
9
10
11
| app.use((err, req, res, next) => {
// 커스텀한 BadRequestError 오류 처리하기
if (err instanceof BadRequestError) {
return res.status(err.statusCode).json({ message: err.message });
}
// 기타 오류처리
return res
.status(StatusCodes.INTERNAL_SERVER_ERROR)
.json({ message: err.message });
});
|
또는
① Custom Error
를 만들고, 각 클래스를 Custom Error
를 확장해서 추가적인 에러 정보 포함시키기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| class CustomError extends Error {
constructor(message, errorCode, statusCode) {
super(message);
this.code = errorCode;
this.statusCode = statusCode;
Error.captureStackTrace(this, this.constructor);
}
}
// Custorm Error 활용해서 오류 생성하기
class BadRequestError extends CustomError {
constructor(message, errorCode) {
super(message, errorCode, StatusCodes.BAD_REQUEST);
this.name = this.constructor.name;
}
}
class UnauthorizedError extends CustomError {
constructor(message, errorCode) {
super(message, errorCode, StatusCodes.UNAUTHORIZED);
this.name = this.constructor.name;
}
}
module.exports = { CustomError, BadRequestError, UnauthorizedError };
|
② 오류 생성
1
2
3
4
5
| const { UnauthorizedError } = require("./errors");
if (!token) {
throw new UnauthorizedError("토큰이 유효하지 않습니다.", "ER_INVALID_TOKEN");
}
|
③ 에러 처리 미들웨어 등록하기
router 가장 마지막에 작성
1
2
3
4
5
6
7
8
| // app.js
const express = require("express");
const app = express();
// 여러개의 router
// 에러 처리 미들웨어 등록 및 사용
app.use(handleError);
|
④ 에러 처리 미들웨어에서 오류 처리하기
err, req, res, next
의 인자를 가짐
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| const { StatusCodes } = require("http-status-codes");
const { CustomError } = require("./errors");
app.use((err, req, res, next) => {
// 커스텀 오류 클래스 확인
if (error instanceof CustomError) {
return res.status(error.statusCode).send({
error: {
message: error.message,
code: error.code,
status: error.statusCode
}
});
}
// 기타 오류 처리
res.status(statusCodes.INTERNAL_SERVER_ERROR).send({
error: {
message: err.message || "서버 내부 오류가 발생했습니다.",
code: "ER_UNKNOWN",
status: statusCodes.INTERNAL_SERVER_ERROR
}
});
});
|