【问题标题】:Is it safe to put error handling in the end event of a Node http request stream?将错误处理放在 Node http 请求流的结束事件中是否安全?
【发布时间】:2017-04-05 10:02:43
【问题描述】:

如果节点请求流返回 200 范围以外的任何 statusCode,我希望记录错误并拒绝请求,但我想从请求中获取响应(如果可用)即使它失败了,因为它有时包含有关失败原因的有用信息.所以我的问题是,如果我在结束事件中检查 statusCode,是否有可能永远不会调用它并且程序会挂起?有没有更好的方法来获取响应正文并拒绝 statusCode?​​p>

const request = http.get(url, (response) => {
            const body = [];
            response.on('data', (chunk) => body.push(chunk));
            response.on('end', () => {
                // handle http errors
                if (response.statusCode < 200 || response.statusCode > 299) {
                    reject(new ErrorClass(response.statusCode, body.join('')));
                } else {
                    resolve(body.join(''))
                }
            });
        });

【问题讨论】:

    标签: node.js


    【解决方案1】:

    传递给回调的responseReadable Stream

    Node.js 文档是这样描述end 事件的:

    当没有更多数据要消耗时,会发出“结束”事件 来自流。

    注意:除非数据是,否则不会发出“结束”事件 完全消耗。这可以通过切换流来完成 进入流动模式,或者通过重复调用 stream.read() 直到所有 数据已被消耗。

    上面提到了data 事件:

    将“数据”事件侦听器附加到尚未被 显式暂停会将流切换到流动模式。数据将 然后尽快通过。

    它说明了error 事件可以由http.request 返回的请求对象发出(其中http.get 是一个特例):

    如果在请求过程中遇到任何错误(对于 DNS 分辨率、TCP 级别错误或实际的 HTTP 解析错误)一个“错误” 在返回的请求对象上发出事件。与所有“错误”一样 事件,如果没有注册监听器,则会抛出错误。

    由于您的代码附加了一个 data 事件侦听器并消耗所有块,因此将在没有更多要消耗的数据后调用 end 数据侦听器 -- 除非 error事件被发出(通常是由于一些潜在的问题阻止了响应处理的完成)。因此,您的代码还应该监听error 事件。例如:

    const request = http.get(url, (response) => {
      const body = [];
      response.on('data', (chunk) => body.push(chunk));
      response.on('end', () => {
        // handle http errors
        if (response.statusCode < 200 || response.statusCode > 299) {
            reject(new ErrorClass(response.statusCode, body.join('')));
        } else {
            resolve(body.join(''))
        }
      });
    });
    request.on('error', (e) => {
      reject(e);
    });
    

    【讨论】:

    • 好答案。但是,我相信错误处理应该在http.get() 上,比如http.get(...).on('error', (e) =&gt; { reject(e); });。就像在docs 中一样。在您拥有错误处理的地方进行错误处理可能会导致未处理的错误。
    • 听起来只要我处理结束和错误事件,我的代码就不会默默地失败。很好的答案,谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-16
    相关资源
    最近更新 更多