如何从nodejs请求中捕获MaxListenersExceededWarning等错误?

时间:2018-03-15 15:05:35

标签: node.js error-handling request

例如,常规try / catch请求不会捕获以下错误:

(node:6432) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 pipe listeners added. Use emitter.setMaxListeners() to increase limit
Error: Exceeded maxRedirects. Probably stuck in a redirect loop https://9.20.65.117/
    at Redirect.onResponse (/XXX/node_modules/request/lib/redirect.js:98:27)
    at Request.onRequestResponse (/XXX/node_modules/request/request.js:990:22)
    at emitOne (events.js:115:13)
    at ClientRequest.emit (events.js:210:7)
    at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:565:21)
    at HTTPParser.parserOnHeadersComplete (_http_common.js:116:23)
    at TLSSocket.socketOnData (_http_client.js:454:20)
    at emitOne (events.js:115:13)
    at TLSSocket.emit (events.js:210:7)
    at addChunk (_stream_readable.js:266:12)

2 个答案:

答案 0 :(得分:2)

您只需在请求选项对象中禁用关注3xx重定向即可 request({followRedirect: false}, ...)

或将Nodejs process.setMaxListeners(0);更改为0(无限制)

答案 1 :(得分:0)

默认情况下,request将进行最多十次重定向。如果您的服务器行为不正常,例如重定向到其自身,则请求将最多跟随该重定向十次,然后返回错误。

但是,请求也侦听传入的请求正文-您可以将Readable传递给request对象,该库将读取并上传该响应。这是通过在请求源代码中注册request.on('pipe', (src) => ...)侦听器来完成的。

问题在于,在每个随后的重定向上,request重新声明了.on('pipe', (src) => ...)侦听器,因此在第7个重定向中,您有7个侦听器,依此类推。默认情况下,在注册了十个相同事件后,EventEmitter会发出警告,这就是为什么您使用EventEmitter和request的默认设置准确地检测到一次可能的内存泄漏的原因。

这可能是一个错误-如果您确实将请求正文通过管道传递到第7个HTTP请求,那么到那时将有七个侦听器,每个侦听器都是独立触发的,并且不清楚会发生什么情况-您可能最终会请求正文重复了7次,或者只是写了7次到未监听的内容。但是,还有一个单独的问题,即仅在第一个请求(而不是所有请求)上发送此管道请求主体,请参见#3138。

所以如果您进行大量重定向,实际上是否存在内存泄漏?可能不是...只要请求对象超出范围,侦听器便已注册在请求对象上(您可以'没有在某处保存对它的引用),那么它将最终收集垃圾并收集事件发射器。

解决方法是什么??在此库中,每次发出新的重定向时,都要注销并重新注册管道处理程序,如果我们遵循以下说明,请不要重新注册管道处理程序:重定向。

在您的代码中,将maxRedirects设置为9或将EventEmitter默认设置为11可能是安全的,只要您的request对象被垃圾回收(它们可能是),这两种方法都可以解决问题。

请注意如果您因除重定向之后以外的行为而{@ {1}} ,则可能仍然存在内存泄漏,请参见https://github.com/request/request/issues/2575