Узел JS асинхронный / ожидающий проблемы с контроллером - PullRequest
0 голосов
/ 26 февраля 2019

Я пытаюсь использовать асинхронную функцию в моем контроллере API Node, но получаю сообщение об ошибке от моего промежуточного программного обеспечения «обработчик ошибок».

TypeError: fn не является функцией в eval (webpack: ///./app/middleware/errorHandler.js?: 16: 21)

Не нравится, когда моя функция 'findAll' экспортируется из моего контроллера, почему это не функция?Правильно ли я экспортирую функцию?Я правильно использую async / await?Нужен ли для этого полифилл?Я понял, что async / await поддерживается с Node v8.В настоящее время я использую Узел v11.10 и Express v4.16.4 .

Вот мой файл маршрутов:

// routes.js
const verifyToken = require('../../middleware/verifyToken.js');
const errorHandler = require('../../middleware/errorHandler.js');

module.exports = app => {
    const controller = require('../../controllers/controller.js');

    app.get(`/collection`, verifyToken, errorHandler(controller.findAll));
}

Вот мойконтроллер:

// controller.js
exports.findAll = async (req, res) => {
    const collections = await collection.find().populate('other');
    res.send(collections);
};

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

// errorHandler.js
module.exports = fn => {
  return (req, res, next) => {
    Promise.resolve(fn(req, res, next)).catch(next);
  };
};

Любая помощь очень ценится.

Ответы [ 2 ]

0 голосов
/ 26 февраля 2019

Я не уверен, но errorHandler ожидает, что fn будет ошибкой?Если так, почему это называется передачей (req, res next)?

Я использую следующую структуру:

Маршрутизатор

// routes.js
const verifyToken = require('../../middleware/verifyToken.js');
const controller = require('../../controllers/controller.js');

var router = express.Router()

router.route('/collection').get(
  verifyToken,
  controller.findAll
)
module.exports = router

Контроллер

// controller.js
const asyncUtil = fn =>
  function asyncUtilWrap(req, res, next, ...args) {
    const fnReturn = fn(req, res, next, ...args)
    return Promise.resolve(fnReturn).catch(next)
  }

module.exports = {
    findAll: asyncUtil(async (req, res, next) => {
        const collections = await collection.find().populate('other'); // you can do try/catch here if you want to handle the error here
        res.send(collections);
};

Тогда обработчик ошибок обычно идет внизу app.js (но вы можете разместить его внизу вашего маршрутизатора):

// app.js 
app.use(function(err, req, res, next) {
  res.status(err.status || 500)
  res.send(err.message)
})
0 голосов
/ 26 февраля 2019

Я думаю, что так и было бы, если бы я вас правильно понял:

// routes.js
const verifyToken = require('../../middleware/verifyToken.js');
const controller = require('../../controllers/controller.js');

module.exports = app => {
  app.get(`/collection`, verifyToken, controller.findAll);
}
// controller.js
exports.findAll = async (req, res, next) => {
  try {
    const collections = await collection.find().populate('other');
    res.send(collections);
  } catch(err) {
    console.log(err); // up to you what to do with the error
    next();
  }
};
...