Express 문서(오류 처리)

6831 단어

오류 처리


오류 처리란 Express가 동기화와 비동기화에서 발생하는 오류를 어떻게 포착하고 처리하는지 말합니다. Express는 기본적인 오류 처리 프로그램을 첨부하기 때문에 자신의 오류 처리 프로그램을 작성하지 않아도 사용할 수 있습니다.

오류 캡처


Express가 루트 프로세서와 중간부품을 실행할 때 발생하는 모든 오류를 포착하는 것을 확보하는 것이 중요하다.
라우팅 프로세서와 중간 부품 내의 동기화 코드에서 발생하는 오류는 별도의 작업이 필요하지 않으며, 동기화 코드에서 오류가 발생하면 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");
  }
]);

위의 예에서 nextfs.writeFile의 리셋으로 제공되며 호출할 때 오류가 있거나 없거나 오류가 없으면 두 번째 처리 프로그램을 실행합니다. 그렇지 않으면 Express가 오류를 포착하고 처리합니다.
라우팅 프로세서나 중간 부품에서 호출되는 비동기 코드에서 발생하는 오류를 포착하여 Express에 전달해야 합니다. 예를 들어 다음과 같습니다.
app.get("/", function (req, res, next) {

  setTimeout(function () {
    try {
      throw new Error("BROKEN");
    }
    catch (err) {
      next(err);
    }
  }, 100);
});

위의 예제에서는 비동기 코드의 오류를 캡처하여 Express에 전달하는 데 try...catch 블록을 사용하는 경우 Express는 동기화 프로세서 코드의 일부가 아니므로 오류를 캡처하지 않습니다.try...catch를 사용하면 promises 블록의 비용을 피하거나promises로 되돌아오는 함수를 사용할 수 있다. 예를 들어 다음과 같다.
app.get("/", function (req, res, next) {
  Promise.resolve().then(function () {
    throw new Error("BROKEN");
  }).catch(next); // Errors will be passed to Express.
});
try...catch는 동기화 오류와 거부promises를 자동으로 포착할 수 있기 때문에 promises를 최종next 프로세서로 간단하게 제공할 수 있습니다. Express는 오류를 포착합니다. catch 프로세서가 오류를 첫 번째 인자로 부여했기 때문입니다.
동기화 오류 캡처에 의존하기 위해 프로세서 체인을 사용할 수도 있습니다. 예를 들어 비동기 코드를 간단한 코드로 줄일 수 있습니다.
app.get("/", [
  function (req, res, next) {
    fs.readFile("/maybe-valid-file", "utf8", function (err, data) {
        res.locals.data = data;
        next(err);
    });
  },
  function (req, res) {
    res.locals.data = res.locals.data.split(",")[1];
    res.send(res.locals.data);
  }
]);

위의 예에는 catch 호출된 간단한 문구가 있습니다. readFile 오류가 발생하면, 오류를 Express에 전달합니다. 그렇지 않으면 체인의 다음 처리 프로그램의 동기화 오류 처리 세계로 빠르게 돌아갈 것입니다.그리고 위의 예시에서 데이터를 처리하려고 시도합니다. 실패하면 동기화 오류 처리 프로그램이 그것을 포착합니다. readFile 리셋에서 이 처리를 완료하면 프로그램이 종료되고 Express 오류 처리 프로그램이 실행되지 않을 수 있습니다.
어떤 방법을 사용하든지 Express 오류 처리 프로그램을 호출하고 프로그램을 살리려면 Express에 오류가 있는지 확인해야 합니다.

기본 오류 처리기


Express는 프로그램에 발생할 수 있는 모든 오류를 처리할 수 있는 내장된 오류 처리 프로그램을 제공합니다. 이 기본 오류 처리 중간부품 함수는 중간부품 함수 창고의 끝에 추가됩니다.
오류를 readFile에 전달하고 사용자 정의 오류 처리 프로그램에서 처리하지 않으면 내장된 오류 처리 프로그램이 처리하고 오류는 창고 추적을 클라이언트에 기록합니다. 창고 추적은 생산 환경에 포함되지 않습니다.
환경 변수next() 설정NODE_ENV 운영 모드에서 어플리케이션을 실행합니다.
응답 쓰기를 시작한 후 production를 호출하고 오류가 발생하면(예를 들어 응답 흐름을 클라이언트로 전송하는 중 오류가 발생하면) Express 기본 오류 처리 프로그램이 연결을 닫고 요청을 실패시킵니다.
따라서 사용자 정의 오류 처리 프로그램을 추가할 때 헤더스가 클라이언트에게 보냈을 때 기본 Express 오류 처리 프로그램에 의뢰해야 합니다.
function errorHandler (err, req, res, next) {
  if (res.headersSent) {
    return next(err)
  }
  res.status(500)
  res.render('error', { error: err })
}

코드 호출 next() 에서 여러 번 오류가 발생하면 기본 오류 처리 프로그램을 터치합니다. 사용자 정의 오류 처리 중간부품이 준비되어 있어도 마찬가지입니다.

오류 처리기 작성


다른 중간부품 함수와 같은 방식으로 오류 처리 중간부품 함수를 정의합니다. 오류 처리 함수를 제외하고는 세 개의 인자가 있습니다. next() 예를 들어:
app.use(function (err, req, res, next) {
  console.error(err.stack)
  res.status(500).send('Something broke!')
})

다른 (err, req, res, next) 와 루트가 호출된 후에 오류 처리 중간부품을 정의할 수 있습니다. 예를 들어:
var bodyParser = require('body-parser')
var methodOverride = require('method-override')

app.use(bodyParser.urlencoded({
  extended: true
}))
app.use(bodyParser.json())
app.use(methodOverride())
app.use(function (err, req, res, next) {
  // logic
})

중간 함수 내의 응답은 HTML 오류 페이지, 간단한 메시지, JSON 문자열 등 모든 형식이 될 수 있습니다.
조직 (더 높은 단계의 프레임워크) 목적에 대해 일반적인 중간부품 함수를 사용하는 것과 같이 여러 개의 오류 처리 중간부품 함수를 정의할 수 있습니다. 예를 들어 XHR을 사용하는 것과 XHR를 사용하지 않는 요청을 위한 오류 처리 프로그램을 정의할 수 있습니다.
var bodyParser = require('body-parser')
var methodOverride = require('method-override')

app.use(bodyParser.urlencoded({
  extended: true
}))
app.use(bodyParser.json())
app.use(methodOverride())
app.use(logErrors)
app.use(clientErrorHandler)
app.use(errorHandler)

이 예에서 공통app.use()은 요청과 오류 정보를 logErrors에 쓸 수 있습니다(예:
function logErrors (err, req, res, next) {
  console.error(err.stack)
  next(err)
}

마찬가지로 이 예에서 stderr의 정의는 다음과 같다. 이런 상황에서 오류는 다음 오류로 명확하게 전달된다.
오류 처리 함수에서'next '를 호출하지 않을 때, 응답을 작성하고 끝내는 것을 책임집니다. 그렇지 않으면 이 요청들은' 마운트 '되고 쓰레기 회수 조건에 부합되지 않습니다.
function clientErrorHandler (err, req, res, next) {
  if (req.xhr) {
    res.status(500).send({ error: 'Something failed!' })
  } else {
    next(err)
  }
}

"catch-all"의 clientErrorHandler 함수는 다음과 같다(예:).
function errorHandler (err, req, res, next) {
  res.status(500)
  res.render('error', { error: err })
}

둘 이상의 콜백 함수를 가진 라우팅 프로세서가 있는 경우 errorHandler 매개변수를 사용하여 다음 라우팅 프로세서로 이동할 수 있습니다. 예를 들어,
app.get('/a_route_behind_paywall',
  function checkIfPaidSubscriber (req, res, next) {
    if (!req.user.hasPaid) {
      // continue handling this request
      next('route')
    }
    else{
      next();
    }
  }, function getPaidContent (req, res, next) {
    PaidContent.find(function (err, doc) {
      if (err) return next(err)
      res.json(doc)
    })
  })

이 예에서는 route 프로세서를 건너뛰지만 getPaidContentapp 나머지 프로세서는 계속 실행됩니다.
맞다/a_route_behind_paywallnext()의 호출은 현재 처리 프로그램이 완성되고 어떤 상태에 있는지 나타낸다.next(err) 상기 오류를 처리하는 프로세서로 설정된 것을 제외하고는 체인의 모든 남은 프로세서를 건너뜁니다.

템플릿 엔진 사용


디버그

좋은 웹페이지 즐겨찾기