(Node.js) express에서 에러로 HTTP status code 통제하기

호두파파·2021년 8월 30일
1

Node.js

목록 보기
21/25
post-custom-banner

throw new Error('BadRequest')

자바스크립트에서 Error를 던져서 에러 처리하는 것은 쉽고 간단한 방법이다.
express에서도 마찬가지이다. Error를 던지면 200 OK가 아닌, 500 Internal Serval Error를 발생시킬 수 있다.

const express = require('express');
const app = express();

app.get('/', (req, res) => {
  throw new Error('BadRequest');
});
app.listen(3000, () => {
  console.log('listen');
});

http-error 이용하기

const express = require('express');
const createError = require('http-errors');
const app = express();

app.get('/', (req, res) => {
  throw new createError.BadRequest();
});
app.listen(3000, () => { console.log('listen') });

내가 원하는 에러코드 넣어주기

http-errors를 쓰는 대신 에러 클래스를 직접 구현하고 싶은 생각이 들지 모른다.
에러 객체에 status 또는 statusCode로 원하는 상태 코드를 넣어준다.

const express = require('express');
const app = express();

app.get('/', (req, res) => {
  const e = new Error('sample');
  e.status = 400;
  throw e;
});
app.listen(3000, () => { console.log('listen') });

라이브러리에서 던져진 에러 제어하기

Error에 status, statusCode를 넣는건 자바스크립트 세상의 표준이 아니다. 그래서 많은 라이브러리의 에러 클래스에는 status, statusCode 속성이 없다.

예제 라이브러리 yup/ValidationError

export default function ValidationError(errors, value, field, type) {
  this.name = 'ValidationError';
  this.value = value;
  this.path = field;
  this.type = type;
  this.errors = [];
  this.inner = [];
  // ...
  this.message =
    this.errors.length > 1
      ? `${this.errors.length} errors occurred`
      : this.errors[0];

  if (Error.captureStackTrace) Error.captureStackTrace(this, ValidationError);
}

위와 같은 라이브러리를 사용하는데 에러가 던져지면 어떻게 대응할까?
catch를 통해서 라이브러리에서 던져진 에러를 잡은 후 http-errors로 다시 던지는 것도 방법이다. 하지만 기존 코드를 전부 catch로 감싸는 것은 너무 무모하다.

express middleware를 사용하기

에러 핸들러에서 err.name를 확인하고 원하는 에러를 대신 던지는 식으로 처리할 수 있다.

const express = require('express');
const createErrors = require('http-errors');
const jwt = require('jsonwebtoken');
const app = express();

app.get('/', (req, res) => {
  throw new jwt.JsonWebTokenError('this is sample error');
});

const newErrorMap = new Map([
  ['JsonWebTokenError', createErrors.BadRequest],
  ['ValidationError', createErrors.BadRequest],
]);

app.use((err, req, res, next) => {
  const newError = newErrorMap.get(err.name);
  if (newError) {
    next(new newError(err.message));
  } else {
    next(err);
  }
});

app.listen(3000, () => { console.log('listen'); });
profile
안녕하세요 주니어 프론트엔드 개발자 양윤성입니다.
post-custom-banner

0개의 댓글