在路线完成后确认使用()

时间:2016-04-08 17:13:42

标签: node.js error-handling restify

我尝试使用"使用()" Restify执行一般错误处理的方法,例如

server = restify.createServer({...});
server.use(restify.acceptParser(server.acceptable));
server.use(restify.queryParser());
server.use(restify.bodyParser());
...
app.post('/test/:id', function (req, res, next) {...})
server.use(function(err, req, res, next) {
      logger.error({req: req}, "error processing request");

    });

但是在路由完成处理后从未调用过最后一个.use()处理程序。 这是"注册"路线之后。我可以在服务器启动时看到,这个.use()是在我的路由处理后处理的。我很难解决,所以我的问题是,.user()方法是否可以在路由完成后应用处理程序。我知道我们可以在'之后听。在路由完成后进行处理的事件,但是想看看我们是否可以做.use()处理程序。

更新: 这是代码的简化版本。调用server.post()之前注册的.use()方法,但不是在server.post()之后注册的方法。有什么建议?

var restify = require('restify');
var cookieParser = require('restify-cookies');
var helmet = require('helmet');
var util = require('util');
var logger = require('./util/logger');


module.exports = function(server){
  server.use(restify.acceptParser(server.acceptable));
  server.use(restify.queryParser());
  server.use(restify.bodyParser());

  server.use(helmet.noCache());
  server.use(helmet.hidePoweredBy());

  server.use(cookieParser.parse);

  // this .use() method is called when accessing the server.post route below
  server.use(function(req, res, next) {
    console.log('BERORE ROUTE');
    return next();
  });

  server.post('/test/:returnId', function (req, res, next) {
    var err = new restify.errors.InternalServerError('oh noes!');
    return next(err);
  });

  // this .use() method is not called when accessing the server.post route above
  server.use(function(req, res, next) {
    console.log('Tata...');
    return next();
  });
};

3 个答案:

答案 0 :(得分:1)

看到

中的代码会很有趣
app.post('/test/:id', function (req, res, next) {
    // what is happening here?
});

我猜你不会调用next,因此永远不会调用下一个中间件(use语句中的日志记录中间件)。因此,调用next()会调用您的中间件。

但也许在你的情况下提出错误并处理错误会更好,如restify docs所述:

app.post('/test/:id', function (req, res, next) {
    // some internal unrecoverable error
    var err = new restify.errors.InternalServerError('oh noes!');
    return next(err);
});

app.on('InternalServer', function (req, res, err, next) {
    //err.body = 'something is wrong!';
    logger.error({req: req}, "error processing request"); // <= from your code
    return next();
});

但这取决于你想要实现的目标以及你在app.post内所做的事情。

答案 1 :(得分:1)

您最后一次“使用”处理程序永远不会被调用的原因是因为在处理程序被分配给路由时它在处理程序链中不存在。对于每个“use”调用,restify将该处理程序添加到处理程序数组中。

当一个路由函数(get,post等)被调用时,restify会创建一个为该路由调用的处理程序链。每条路由的处理程序链都是根据您为该路由传递的内容构建的,并且它是PREPENDED,其中包含迄今为止通过“use”调用找到的所有处理程序。

因此,当处理server.post函数调用时,处理程序链中尚不存在“Tata ...”处理程序,因此它不会被预先添加。这就是为什么所有“使用”呼叫总是放在路线上方。

为了说明这一点,我在restify中的server.use函数中放置了两个console.log语句。您可以使用中间件处理程序查看链构建(我将您的函数命名为“before”和“error_handler”,以便可以在输出中识别它们)。您可以看到对server.use的最后一次调用导致包含所有中间件处理程序的链,但posttestreturnId路由的处理程序不包含“error_handler”,因为它在调用时不在数组中。

[ [Function: parseAccept] ] // the handler chain
{}                          // the routes and their handlers
[ [Function: parseAccept],
  [Function: parseQueryString] ]
{}
[ [Function: parseAccept],
  [Function: parseQueryString],
  [Function: readBody],
  [Function: parseBody] ]
{}
[ [Function: parseAccept],
  [Function: parseQueryString],
  [Function: readBody],
  [Function: parseBody],
  [Function: nocache] ]
{}
[ [Function: parseAccept],
  [Function: parseQueryString],
  [Function: readBody],
  [Function: parseBody],
  [Function: nocache],
  [Function: hidePoweredBy] ]
{}
[ [Function: parseAccept],
  [Function: parseQueryString],
  [Function: readBody],
  [Function: parseBody],
  [Function: nocache],
  [Function: hidePoweredBy],
  [Function: parseCookies] ]
{}
[ [Function: parseAccept],
  [Function: parseQueryString],
  [Function: readBody],
  [Function: parseBody],
  [Function: nocache],
  [Function: hidePoweredBy],
  [Function: parseCookies],
  [Function: before] ]
{}
[ [Function: parseAccept],
  [Function: parseQueryString],
  [Function: readBody],
  [Function: parseBody],
  [Function: nocache],
  [Function: hidePoweredBy],
  [Function: parseCookies],
  [Function: before],
  [Function: error_handler] ]
{ posttestreturnid: 
  [ [Function: parseAccept],
    [Function: parseQueryString],
    [Function: readBody],
    [Function: parseBody],
    [Function: nocache],
    [Function: hidePoweredBy],
    [Function: parseCookies],
    [Function: before],
    [Function: returnId] ] }

答案 2 :(得分:0)

如果你想在其他路由不使用server.use()之后执行一个函数,而是使用下面的代码。

 // this .use() method is called when accessing the server.post route below
server.use(function(req, res, next) {
  console.log('BERORE ROUTE');
  return next();
});

server.post('/test/:returnId', function (req, res, next) {
  var err = new restify.errors.InternalServerError('oh noes!');
  return next(err);
});

server.on('after', function(req, res, next) {
  console.log('Tata...');
  return next();
});

如图所示http://restify.com/#audit-logging

相关问题