如何捕捉request抛出的异常

request是用Node.js编写的一个HTTP客户端库,用于发出HTTP/HTTPS协议的请求,项目主页在此。它提供回调风格的API,例如下面的代码将访问example.com并将页面源码输出到终端

'use strict';

const request = require('request');

request('http://example.com/', function (error, response, body) {
  if (error) {
    console.error(error);
  } else {
    console.log(body);
  }
});

保存到文件request-example.js中,在命令行执行下列代码即可看到效果

node request-example.js

除了网页之外,request当然也可以请求HTTP协议的服务端API。但如果只是想要请求一下接口,而不需要获得响应结果时,可能会写出下面这样的代码

'use strict';

const request = require('request');

request('http://example.com/');

这样确实可以对服务端API发出请求,可以在本地启动一个Web服务器验证这一点,例如使用下列命令

python -m SimpleHTTPServer 8000

就可以启动一个监听8000端口的HTTP服务器了。将request-example.js文件中的目标地址改为http://127.0.0.1:8000/后再执行,就可以看到Web服务器在终端输出了一行访问日志。

可如果请求服务端API的过程中遇到了问题,上面的代码将会怎样呢?我最开始认为,既然回调函数的第一个参数是用于接收可能出现的错误的,那么如果没有回调函数,这个错误无处可去,这个它应该会被安静地丢掉。为了验证这个猜想,我把将本地的Web服务器关闭,然后再执行这段Node.js代码,结果在我的电脑上,node输出了如下信息

events.js:160
      throw er; // Unhandled 'error' event
      ^

Error: connect ECONNREFUSED 127.0.0.1:8000
    at Object.exports._errnoException (util.js:1022:11)
    at exports._exceptionWithHostPort (util.js:1045:20)
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1087:14)

出乎意料,request居然抛出了异常,这是为什么呢?阅读request的源代码后发现,如果调用request时提供了回调函数,那么下面这段代码会使用这个回调函数来处理error事件

  if (!self._callback && self.callback) {
    self._callback = self.callback
    self.callback = function () {
      if (self._callbackCalled) {
        return // Print a warning maybe?
      }
      self._callbackCalled = true
      self._callback.apply(self, arguments)
    }
    self.on('error', self.callback.bind()) // <-- 就是这一句
    self.on('complete', self.callback.bind(self, null))
  }

而如果没有传入回调函数,那么当请求对象(self.req)收到error事件时,会调用onRequestError方法,并在Request对象上主动发送'error'事件。由于没有处理'error'事件的回调函数,因此在onRequestError方法中抛出的错误,将会成为一个'uncaughtException',一直抛出到node进程这一级(因为对node的事件机制不是很清楚,这一部分只是我的猜测)。如果没有对'uncaughtException'事件进行处理,node进程就会被终止并输出上文所看到的错误信息。

因此,如果要在不传递回调函数的情况下忽略可能发生的网络错误,应当使用下面的代码

'use strict';

const request = require('request');

process.on('uncaughtException', function (error) {
  console.error('catch uncaughtException', error);
});

request('http://127.0.0.1:8000/');

老实说,上面的代码还不如写成

'use strict';

const request = require('request');

request('http://127.0.0.1:8000/', function (error) {
  console.error(error);
});

我的目的只在于请求服务端API而不在意失败,因此最终的代码如下

'use strict';

const request = require('request');

request('http://127.0.0.1:8000/', function () {});
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容