【问题标题】:Express.js connect-timeout. how to handle when timout fire,where it generate errorExpress.js 连接超时。 timout触发时如何处理,它在哪里产生错误
【发布时间】:2015-10-23 20:57:29
【问题描述】:

当我在超时触发时使用连接超时时,它会显示

[2015-07-31 11:46:18.983] [ERROR] console - ServiceUnavailableError:
Response timeout
      at IncomingMessage. (/opt/data/nlb-server-dev/node_modules/connect-timeout/index.js:69:8)
      at IncomingMessage.EventEmitter.emit (events.js:95:17)
      at null._onTimeout (/opt/data/nlb-server-dev/node_modules/connect-timeout/index.js:41:11)
    at Timer.listOnTimeout as ontimeoutenter
[2015-07-31 11:46:18.990] [ERROR] exception-log - Server web-server-1: Caught
exception: Error: Can't set headers after they are sent. stack: Error:
Can't set headers after they are sent.   at
ServerResponse.OutgoingMessage.setHeader (http.js:691:11)    at
ServerResponse.res.set.res.header
(/opt/data/nlbserverdev/node_modules/express/lib/response.js:561:10)  
at ServerResponse.res.send
(/opt/data/nlbserverdev/node_modules/express/lib/response.js:133:12)
at ServerResponse.res.json
(/opt/data/nlb-server-dev/node_modules/express/li
b/response.js:210:15)at ServerResponse.res.send
(/opt/data/nlb-server-dev/node_modules/express/lib/response.js:121:21)
at /opt/data/nlb-server-dev/app/services/web/adminHandler.js:110:9 at
Object.utils.invokeCallback
(/opt/data/nlb-server-dev/app/util/utils.js:9:8) at
/opt/data/nlb-server-dev/app/dao/baseDao.js:48:13 at Query._callback
(/opt/data/nlb-server-dev/app/dao/mysql/mysql.js:55:9) at
Query.Sequence.end
(/opt/data/nlb-server-dev/node_modules/mysql/lib/proto
col/sequences/Sequence.js:78:24)

我处理如下,但它不起作用

function errorFilter(err, req, res, next){
  logger.warn(err.stack);
  errcode = err.statusCode || 500;
  msg = err.message || 'server error!';
  res.send(errcode, msg);
}

我看到 middiwire 我找不到如何处理它。请帮帮我。

【问题讨论】:

  • 当超时发生时我该如何处理

标签: node.js express connect-timeout


【解决方案1】:

虽然您的错误处理程序可能需要稍作调整,但这不是您的问题。

如错误所示,您正尝试在已发送标头后发送标头。由于一旦为 res 发出标头,connect-timeout 就会自行结束,因此您要么尝试在调用 connect-timeout 之前发送标头,要么在它的计时器计时结束后发送标头。

  1. 如果是在调用connect-timeout之前,这很简单,你只需要确保它的中间件在任何其他有输出的中间件之前。这个选项似乎不太可能,因为通常任何带有输出的中间件都不会推卸责任。
  2. 如果是在计时器计时结束后,那么您的函数(只有在您告诉它时才知道停止处理)正在尝试输出某些内容。要解决此问题,请在发送任何内容之前至少检查 req.timedout,如果为真,请停止处理

图 A

var express = require('express');
var app = express();
var timeout = require('connect-timeout');
var createError = require('http-errors'); //this is required by connect-timeout, so you should already have it

app.get('/long/query/',timeout('5s'),function(req,res,next){
    if(req.timedout)return next(createError(503,'Response timeout'));
    //Something that takes a long time
    if(req.timedout)return next(createError(503,'Response timeout'));
    req.send("I processed that for you!");
});

var errorFilter = function(err, req, res, next){
    logger.warn(err.stack); //the stack is actually not going to be helpful in a timeout
    if(!res.headersSent){ //just because of your current problem, no need to exacerbate it.
        errcode = err.status || 500; //err has status not statusCode
        msg = err.message || 'server error!';
        res.status(errcode).send(msg); //the future of send(status,msg) is hotly debated
};

app.use(errorFilter);
app.listen(80);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-15
    • 2016-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-23
    • 1970-01-01
    相关资源
    最近更新 更多