Извикване на следващия вътре в помощна функция?

Опитвам се да настроя проста система за изобразяване на грешки при въвеждане от потребителя и спиране на разпространението в експресен режим, това е, което имам досега:

routingFunction= (req, res, next) {
  //setting up a test in express-validator
  var test = req.assert('access_token', 'required').notEmpty();
  isValid(test, next);
  //non error stuff
}

isValid = (tests, next) => {
    //some more code here, that checks if any errors were found and save tem to the array errors.
    if(errors.length > 0){
        return next(new Error());
    }
};

 //a middleware that catches errors:
 app.use((err, req, res, next) => {
     res.json('error').end();
 });

Проблемът ми с това е, че не спира разпространението, когато извиквам Next(new Error());, мога да върна true/false от isValid и след това да върна next(new Error()), но това би добавило много раздуване към моите контролери , има ли някакъв по-добър начин да го направите от помощната функция?


person Himmators    schedule 16.07.2016    source източник


Отговори (2)


В основния маршрутен файл, напр. routes/index.js

// Set of func(req, res, next)
let v = require('validator'); // middleware-validators
let user = require('user'); // routes for user 
...
app.get('/smth-route-of-user', v.isTokenSet, v.isEmail, ..., user.get)

In middlewares/validator.js

let v = require('validator-func-list');
...
exports.isTokenSet = function (req, res, next) {
    if (v.isValid(req.body.token))
        next(); // Forwarding to next middleware. In our route next() called v.isEmail
    else
        next(new Error('Token is empty')); // Stop route chain and call error-middleware;
}

exports.isEmail = function (req, res, next) {
... 

Можете да присъедините валидатори към един, напр. checkUser() и използвайте само един в route.

In middlewares/errorHandler.js

module.exports = function (err, req, res, next) {
    let msg = err.message; // Here we see 'Token is empty';

    if (req.xhr)
         res.json(msg);
    else
         res.render('error_page.html', {message: msg, ...});

    // Here we can call next(err) to forwarding error to next errorHandler. In example below it was errorHandler2.
}

В app.js не забравяйте да прикачите грешка междинен софтуер към приложението.

app.use(require('middlewares/errorHandler'));
app.use(require('middlewares/errorHandler2'));

Ако имате нужда от събиране на грешки, тогава валидаторът трябва да изпрати грешката до req.errors (или друго поле, както искате) и да извика next() без грешка. В междинния софтуер за изобразяване вие ​​просто проверявате req.errors.length и показвате нормална страница или страница с грешка.

person Aikon Mogwai    schedule 17.07.2016
comment
Това е почти моята настройка, проблемът, който имам, е, че след next(new Error() и тази функция е готова, изглежда, че функцията isValid се връща и изпълнява кода //non error stuff, не искам това, тъй като валидирането не премина . - person Himmators; 17.07.2016

Кодът след isValid(test, next); винаги се изпълнява. Кодът по-долу го блокира, но imho е мръсен.

routingFunction = (req, res, next) {
  var test = req.assert('access_token', 'required').notEmpty();
  if (!isValid(test, next)) 
      return; // callback called by isValid. It's dust.

  //non error stuff
  ...
  next(); // callback must be called 
}

isValid = (tests, next) => {
    if(errors.length > 0){
        next(new Error());
        return false;
    }
    return true; 
};

Още по-добро използване като това

routingFunction = (req, res, next) {
  var test = req.assert('access_token', 'required').notEmpty();
  if (!isValid(test)) 
      return next (new Error('error description'));

  //non error stuff
  ...
  next();
}
person Aikon Mogwai    schedule 17.07.2016