Yunseok's Dev Blog

배운 것을 적는 블로그입니다.

Express Error Handling

  • 에러핸들링은 익스프레스가 에러를 어떻게 캐치하고 처리하는지를 나타냅니다.
  • 익스프레스는 기본 에러 핸들러를 포함하고 있어서 지금은 코드를 직접적으로 작성할 필요는 없습니다.

Catching Errors

  • 라우트핸들러와 미들웨어를 실행하는중에 발생하는 모든 에러를 캐치해야 합니다.
  • 라우트와 미들웨어에서 synchronous코드에서 발생하는 오류에서는 특별히 할 일은 없습니다.
  • synchronous코드에서 에러가 발생한다면 Express는 캐치하여 처리합니다.
app.get("/", function (req, res) {
  throw new Error("BROKEN"); // Express will catch this on its own.
});
  • 하지만 라우트 핸들러와 미들웨어에서 비동키 함수들에서 에러가 발생한다면 반드시 next()함수를 통해 에러를 전달해줘야 합니다.
app.get("/", function (req, res, next) {
  fs.readFile("/file-does-not-exist", function (err, data) {
    if (err) {
      next(err); // Pass errors to Express.
    }
    else {
      res.send(data);
    }
  });
});
  • next()함수 인자로 (route를 제외하고) 어떤 것이는 전달하면 Express는 현재 요청에 에러가 있고 남은 에러 핸들링을 하지 않는 라우팅이나 미들웨어 함수들을 건너 뛸 것입니다.
  • 만약 콜백함수의 결과가 에러말고는 리턴하는 값이 없다면 다음과 같이 간단하게 작성할 수 있습니다.
app.get("/", [
  function (req, res, next) {
    fs.writeFile("/inaccessible-path", "data", next);
  },
  function (req, res) {
    res.send("OK");
  }
]);
  • 위의 예에서 fs.writeFile의 콜백 함수로 next함수가 전달 되었습니다.
  • 에러가 없으면 두 번째 핸들러가 실행되고 그렇지 않으면 Express가 에러를 캐치하고 처리합니다.
  • 라우트 핸들러나 미들웨어에 비동기코드에서 발생하는 에러는 반드시 캐치하여야 합니다.
app.get("/", function (req, res, next) {

  setTimeout(function () {
    try {
      throw new Error("BROKEN");
    }
    catch (err) {
      next(err);
    }
  }, 100);
});
  • 위에 예는 try...catch블락을 사용합니다. 비동기코드에서 에러를 캐치하고 Express로 전달합니다.
  • 만약 try...catch블락이 생략된다면 Express는 에러를 캐치하지 않을 것 입니다.
  • promise를 사용하거나 promise를 반환하는 함수를 이용해서 try...catch블락의 오버헤드를 피할 수 있습니다.
app.get("/", function (req, res, next) {
  Promise.resolve().then(function () {
    throw new Error("BROKEN");
  }).catch(next); // Errors will be passed to Express.
});