개발을 진행하면서 CRUD만 작성을 하다보니깐 에러를 처리하는 부분이 마음에 들지 않아서!!
특히, catch부분에 ctrl + c , ctrl + v 로 500에러만 나타내주기 보다는 각각의 상황에 맞춰 에러를 핸들링 해주고 싶었습니다.
 구글링을 통해서 best practice를 찾아보고 적용하면서 부족한 부분이 무엇인지에 대해서도 알 수 있었습니다.
next()의 동작과 app.js의 플로우와 app.use를 세밀하게 더 살펴볼 수 있었고 제 코드에 적용할 수 있었던 기회였습니다!

controlloer/user.controller.js

const userService = require('../services/user.service');
const HttpStatusCode = require('../config/httpStatusCode');

module.exports = {
    findAllUser: async (req, res) => {
        try {
            const user = await userService.read();
            if (user.length !== 0) return res.status(400).send({ statusCode: 400, message: "Bad Request" });
            return res.status(200).send({ data: user, statusCode: 200 });
        } catch (error) {
            res.status(500).send({ statusCode: 500, message: "Server Error" });
        }
    }
}

 

결과  

위의 controller의 에러 처리

구글링을 통해 Error Best Practice 찾아봐서 내 코드에 적용해보기

config/httpStatusCode.js

const HttpStatusCode = {
    OK: 200,
    BAD_REQUEST: 400,
    NOT_FOUND: 404,
    INTERNAL_SERVER: 500,
}

module.exports = HttpStatusCode;

error/error.js

const HttpStatusCode = require('../config/httpStatusCode');

class BaseError extends Error {

    constructor(name, httpCode, description, isOperational) {
        super(description);
        Object.setPrototypeOf(this, new.target.prototype);

        this.name = name;
        this.httpCode = httpCode;
        this.isOperational = isOperational;

        Error.captureStackTrace(this);
    }
}
//free to extend the BaseError
class APIError extends BaseError {
    constructor(name, httpCode = HttpStatusCode.INTERNAL_SERVER, isOperational = true, description = 'internal server error') {
        super(name, httpCode, isOperational, description);
    }
}

module.exports = { BaseError, APIError };

 

 

 

middlewares/errorHandler.js

function logError(err) {
    console.error(err)
}

function logErrorMiddleware(err, req, res, next) {
    logError(err)
    next(err)
}

function returnError(err, req, res, next) {
    res.status(err.statusCode || 500).send(err.message)
}

function isOperationalError(error) {
    if (error instanceof BaseError) {
        return error.isOperational
    }
    return false
}

module.exports = {
    logError,
    logErrorMiddleware,
    returnError,
    isOperationalError
}

자 그러면, 기존의 Controller에 적용을 하기 전에 app.js에서 middleware를 app.use()를 통해 등록해줍니다.

const express = require('express');
const userRouter = require('./routes/userRouter');
const logger = require('./logger/logger');
const { APIError } = require('./errors/error');
const { logError, returnError, logErrorMiddleware } = require('./middlewares/error1');


const app = express();

app.use(express.json());

app.use('/user', userRouter);
app.use(APIError);
app.use(logError);
app.use(logErrorMiddleware)
app.use(returnError);
app.use(logHandler);

app.listen(3030, () => {
    logger.info('server is running!');
});

Controller에 적용해보기

const userService = require('../services/user.service');
const HttpStatusCode = require('../config/httpStatusCode');
const { APIError } = require('../errors/error');

module.exports = {
    findAllUser: async (req, res, next) => {
        try {
            const user = await userService.read();
            if (user.length !== 0) throw new APIError("Bad Request", HttpStatusCode.BAD_REQUEST, true, "Bad Request");
            return res.status(200).send({ data: user, statusCode: 200 });
        } catch (error) {
            next(error);
        }
    }
}

 

결과 

예제 적용한 후의 결과
log

참고 사이트 : https://sematext.com/blog/node-js-error-handling/

+ Recent posts