【问题标题】:How to catch node TimeoutError and log the request?如何捕获节点 TimeoutError 并记录请求?
【发布时间】:2017-11-12 19:20:58
【问题描述】:

我正在节点中编写一个应用程序,在该节点中我向远程服务发出许多 websocket 请求(使用ws library)。所以远程服务是服务器,我的节点应用程序是客户端。它工作得很好,但偶尔我会突然得到以下 TimeoutError 的长列表:

Unhandled rejection TimeoutError: ResourceRequest timed out
    at ResourceRequest._fireTimeout (/Users/kramer65/repos/mmj/node_modules/generic-pool/lib/ResourceRequest.js:58:17)
    at Timeout.bound (/Users/kramer65/repos/mmj/node_modules/generic-pool/lib/ResourceRequest.js:8:15)
    at ontimeout (timers.js:386:11)
    at tryOnTimeout (timers.js:250:5)
    at Timer.listOnTimeout (timers.js:214:5)

由于我进行了许多不同的 websocket 调用,我现在想知道这个错误发生在哪个调用上。我尝试将ws.send() 包装在下面粘贴的 try/catch 中,但这似乎没有任何作用。

try {
    ws.send(request_json);
} catch(e) {
    console.log('WEBSOCKET ERROR', e);
    console.log('WEBSOCKET JSON', request_json);
}

有人知道我如何捕捉 TimeoutError 并记录请求内容吗?欢迎所有提示!

[编辑] 正如@Mark_M 所建议的,我向 ws.send() 方法添加了一个回调,如下所示:

ws.send(JSON.stringify(request_obj)), (error)=>{
    console.log('WEBSOCKET ERROR', request_obj.action, error);
});

不幸的是,我仍然遇到与我在此问题顶部发布的相同的错误。

[编辑2] 我也尝试了@wrangler 提出的建议:

ws.send(JSON.stringify(request_obj));
ws.onerror = function(event) {
    console.log('WEBSOCKET ONERROR', request_obj.action, event);
};
ws.onclose = function (event){
    console.log('WEBSOCKET ONCLOSE', request_obj.action, event);
};

但不幸的是,这似乎也不起作用。我仍然收到与我在此问题顶部发布的相同的错误。

还有其他想法吗?

【问题讨论】:

    标签: node.js websocket timeout try-catch


    【解决方案1】:

    ws.library send() 方法采用可选的回调,当遇到错误时将调用该回调。您可以通过以下方式捕获这些错误:

    ws.send('something', function ack(error) {
       if(error) //handle error
    }
    

    Try/catch 会立即捕获错误,但正如您所注意到的,它对异步错误没有帮助。

    另外,您似乎在其他一些异步代码中调用send()(因为您不仅收到错误,而且收到未处理的承诺拒绝)。如果它在您自己的代码中,您可以在该 Promise 上添加 .catch()

    【讨论】:

    • 我试过你的代码,但是一旦我这样做了,我仍然得到和以前一样的错误。因此它们不会被 ack 错误回调捕获。我将它添加到我最初的问题中。知道我做错了什么吗?
    【解决方案2】:

    您可以使用 websocket 对象的onerror 回调来接收任何错误。

    例子:

    var exampleSocket = new WebSocket("ws://echo.websocket.org");
        exampleSocket.onopen = function (event) {
            console.log("open");
          exampleSocket.send("hellow world"); 
        };
        exampleSocket.onmessage = function (event) {
          console.log(event.data);
        }
    
        exampleSocket.onerror=function(event){
            console.log("Error");
        }
    

    链接:http://jsfiddle.net/g28yuymv/1/

    链接2:http://jsfiddle.net/g28yuymv/10/

    【讨论】:

    • 我尝试了你的建议,但不幸的是我仍然得到了我最初得到的Unhandled rejection TimeoutError。知道我还能做些什么来解决这个问题吗?
    【解决方案3】:

    好吧,我傻了。在更好地查看初始错误后,我发现这是generic-pool 包中的错误。在its npm page 它说它是

    基于 Promise 的 API,可用于重用或限制 数据库连接等昂贵的资源

    问题原来是我的数据库连接(它被广泛使用)。我使用this tip on github解决了它,它建议将sequelize init pool设置设置如下:

    池:{最大值:5,最小值:0,空闲:20000,获取:20000}

    这为我解决了这个问题。

    多亏了答案,我现在有了正确的 websocket 错误报告.. :-)

    【讨论】:

      猜你喜欢
      • 2021-06-17
      • 1970-01-01
      • 1970-01-01
      • 2019-01-25
      • 2019-04-28
      • 2018-12-31
      • 2017-12-02
      • 2013-06-27
      • 1970-01-01
      相关资源
      最近更新 更多