NodeJs UnhandledPromiseRejectionWarning: Ошибка [ERR_HTTP_HEADERS_SENT]: невозможно установить заголовки после их отправки клиенту - PullRequest
0 голосов
/ 12 июля 2020

Здравствуйте, я работаю над задачей проверки пользователя с использованием промежуточного программного обеспечения, чтобы проверить, существует ли пользователь или нет, это мой код:

У меня конечная точка определена следующим образом:

app.get("/login/", verifyUser, userController.login); 

Это мое промежуточное ПО verifyUser:

function verifyUser(req, res, next) {
  console.log("Midd 1:", req.query);
  let userInfo = userController.findUserOne(req, res);
  console.log("userInfo:" + userInfo);
  next();
}

Это мой метод контроллера:

exports.findUserOne = function (req, res) {
  (async () => {
    try {
      var query = db
        .collection("users")
        .where("user", "==", req.query.user)
        .where("password", "==", req.query.password);
      query.get().then(function (querySnapshot) {
        if (querySnapshot.size > 0) {
          const accessToken = generateAccessToken({ name: req.query.user });
          res.json({ accessToken: accessToken });
        } else {
          return res.status(500).send("User doesn't exist:");
        }
      });
    } catch {
      return res.status(500).send(error);
    }
  })();
};

После вызова конечной точки входа я получаю следующее сообщение об ошибке:

(node:12468) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:485:11)
    at ServerResponse.header (C:\Tools\Node\From Github\NodeAndReact-FullStack\server\node_modules\express\lib\response.js:771:10)
    at ServerResponse.send (C:\Tools\Node\From Github\NodeAndReact-FullStack\server\node_modules\express\lib\response.js:170:12)
    at ServerResponse.json (C:\Tools\Node\From Github\NodeAndReact-FullStack\server\node_modules\express\lib\response.js:267:15)
    at C:\Tools\Node\From Github\NodeAndReact-FullStack\server\controllers\users\userController.js:54:15
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
(node:12468) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:12468) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Я обрабатываю свой блок asyn c в контроллере, пытаясь поймать, но, судя по внешнему виду, похоже, что проблема связана с этим. На самом деле я не совсем уверен, лучший ли это способ реализовать эту проверку, или у меня проблема, связанная с кодом asyn c.

Ответы [ 2 ]

0 голосов
/ 12 июля 2020

это потому, что userController.findUserOne является асинхронной c функцией, в то время как вы вызываете ее без какого-либо ожидания. поэтому в этой части вашего кода

function verifyUser(req, res, next) {
    console.log("Midd 1:", req.query);
    let userInfo = userController.findUserOne(req, res);
    console.log("userInfo:" + userInfo);
    next();
}

, когда вы вызываете userController.findUserOne(req, res);, поскольку функции asyn c возвращают обещание, он вернет обещание, а не реальную информацию о пользователе, которую вы хотите.

решение состоит в том, чтобы изменить функцию verifyUser на что-то вроде этого:

async function verifyUser(req, res, next) {
    try {
        console.log("Midd 1:", req.query);
        let userInfo = await userController.findUserOne(req, res);
        console.log("userInfo:" + userInfo);
        next();
    } catch(error){
        //handle exceptions here
    }
}
0 голосов
/ 12 июля 2020

Ошибка Error [ERR_HTTP_HEADERS_SENT] возникает, когда ответ уже отправлен пользователю. Здесь userController.findUserOne(req, res) - это async. Так что js его не ждет и вызывается next(). Это вызывает состояние гонки.

Промежуточное ПО не должно напрямую вызывать методы контроллеров, поскольку эти методы в конечном итоге отправляют запрос пользователю. Вы можете создать папку utils, которая может содержать файлы для выполнения всех этих логических действий и возврата данных обратно в промежуточное программное обеспечение, а не для отправки ответа пользователю. Кроме того, вам нужно связать цепочку с .then(), чтобы дождаться результатов, а затем вызвать в нем next().

Но я думаю, вы можете переместить все эти logi c на userController.login. Отдельного промежуточного программного обеспечения не требуется.

...