errorGenerator라는 별도의 함수를 두고 error가 발생할 때 동적으로 statusCode를 넣어주는 방식으로 변경!
userController.ts의 일부
export const signUpUser = async (
req: IRequest,
res: Response,
next: NextFunction
) => {
try {
const { name, email, password } = req.body;
if (!name || !email || !password) {
//ErrorGenerate 만들기
throw new Error("항목을 빠짐없이 입력해주세요");
}
const newUser = await createUserService(name, email, password);
res.status(200).json(newUser);
} catch (error) {
next(error);
}
};
try catch를 이용해서 error가 발생하면 next를 이용하거나
throw new Error를 이용한 early return 방식 사용해서 errorMiddleware로 넘기는 방식
logger.ts
function errorMiddleware(error : Error, req : Request, res : Response, next : NextFunction) : void {
logger.error(error);
res.status(400).send(error.message);
}
errorMiddleware의 모습 기존에는 statusCode를 400으로 박아놓고 사용
error.ts
export interface IError extends Error {
statusCode?: number | null | undefined;
}
errorGenerator를 보여주기 전에 먼저 사용할 에러에 대한 type을 선언해줌
기본 Error type을 extends 해줬다
null 이랑 undefined가 들어간 이유는 statusCode에서 숫자가 안 들어오게 될 때를 다뤄주기 위함이다!
errorGenerator.ts
import { IError } from "error";
export const errorGenerator = (
errorMessage: string,
statusCode: number
): IError => {
const error: IError = new Error(errorMessage);
error.statusCode = statusCode;
return error;
};
errorMessage와 statusCode를 인자로 넣어준다.
new Error에 errorMessage를 넣어서 에러를 생성해주고, error 객체에 statusCode를 넣어준다!
userValidator.ts
export const validateUpdateUser = (
req: IRequest,
res: Response,
next: NextFunction
) => {
const updateValue = req.body;
const schema = joi.object({
name: joi.string().min(2).max(20).optional().pattern(nameReg),
description: joi.string().optional(),
uploadFile: joi.any(),
});
const { error } = schema.validate(updateValue);
if (error) {
const err = errorGenerator(error.details[0].message, 400);
next(err);
}
next();
};
errorGenerator에 에러메세지랑 에러코드를 보내주고 next(err)로 에러미들웨어로 에러를 보내준다.
userController.ts
export const signUpUser = async (
req: IRequest,
res: Response,
next: NextFunction
) => {
try {
const { name, email, password } = req.body;
const newUser = await createUserService(name, email, password);
res.status(200).json(newUser);
} catch (error) {
next(error);
}
};
userService.ts
export const createUserService = async (
name: string,
email: string,
password: string
): Promise<IUser> => {
const user = await findUserByEmail(email);
if (user) throw errorGenerator("이미 존재하는 이메일 입니다.", 400);
const hashedPassword = await bcrypt.hash(password, 10);
const createdUser = await create(name, email, hashedPassword);
return createdUser;
};
error.message를 errorGenerator의 첫번째 인자로 넘겨주고 상황에 맞는 statusCode를 직접 넘겨준다.
thorw ,next()로 넘기는 건 기존과 동일
logger.ts
function errorMiddleware(
error: IError,
req: Request,
res: Response,
next: NextFunction
): void {
if (error.statusCode === null || error.statusCode === undefined)
error.statusCode = 500;
logger.error(
`statusCode: ${error.statusCode} | Error Message: ${error.message} `
);
res.status(error.statusCode).send(error.message);
}
기존에는 statusCode를 직접 상수로 써주었지만 지금은 error.statusCode로 넘겨준다!
그리고 내가 핸들링해주지 못한 에러의 경우 statusCode가 없을테니까 statusCode가 null이거나 undefind 일 경우엔 statusCode를 500으로 해서 처리~