如何捕捉request拋出的異常

request是用Node.js編寫(xiě)的一個(gè)HTTP客戶端庫(kù)面哼,用于發(fā)出HTTP/HTTPS協(xié)議的請(qǐng)求,項(xiàng)目主頁(yè)在此扫步。它提供回調(diào)風(fēng)格的API魔策,例如下面的代碼將訪問(wèn)example.com并將頁(yè)面源碼輸出到終端

'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中,在命令行執(zhí)行下列代碼即可看到效果

node request-example.js

除了網(wǎng)頁(yè)之外河胎,request當(dāng)然也可以請(qǐng)求HTTP協(xié)議的服務(wù)端API闯袒。但如果只是想要請(qǐng)求一下接口,而不需要獲得響應(yīng)結(jié)果時(shí),可能會(huì)寫(xiě)出下面這樣的代碼

'use strict';

const request = require('request');

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

這樣確實(shí)可以對(duì)服務(wù)端API發(fā)出請(qǐng)求政敢,可以在本地啟動(dòng)一個(gè)Web服務(wù)器驗(yàn)證這一點(diǎn)原茅,例如使用下列命令

python -m SimpleHTTPServer 8000

就可以啟動(dòng)一個(gè)監(jiān)聽(tīng)8000端口的HTTP服務(wù)器了。將request-example.js文件中的目標(biāo)地址改為http://127.0.0.1:8000/后再執(zhí)行堕仔,就可以看到Web服務(wù)器在終端輸出了一行訪問(wèn)日志擂橘。

可如果請(qǐng)求服務(wù)端API的過(guò)程中遇到了問(wèn)題,上面的代碼將會(huì)怎樣呢摩骨?我最開(kāi)始認(rèn)為通贞,既然回調(diào)函數(shù)的第一個(gè)參數(shù)是用于接收可能出現(xiàn)的錯(cuò)誤的,那么如果沒(méi)有回調(diào)函數(shù)恼五,這個(gè)錯(cuò)誤無(wú)處可去昌罩,這個(gè)它應(yīng)該會(huì)被安靜地丟掉。為了驗(yàn)證這個(gè)猜想灾馒,我把將本地的Web服務(wù)器關(guān)閉茎用,然后再執(zhí)行這段Node.js代碼,結(jié)果在我的電腦上睬罗,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的源代碼后發(fā)現(xiàn)古涧,如果調(diào)用request時(shí)提供了回調(diào)函數(shù),那么下面這段代碼會(huì)使用這個(gè)回調(diào)函數(shù)來(lái)處理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))
  }

而如果沒(méi)有傳入回調(diào)函數(shù)花盐,那么當(dāng)請(qǐng)求對(duì)象(self.req)收到error事件時(shí)羡滑,會(huì)調(diào)用onRequestError方法,并在Request對(duì)象上主動(dòng)發(fā)送'error'事件算芯。由于沒(méi)有處理'error'事件的回調(diào)函數(shù)柒昏,因此在onRequestError方法中拋出的錯(cuò)誤,將會(huì)成為一個(gè)'uncaughtException'熙揍,一直拋出到node進(jìn)程這一級(jí)(因?yàn)閷?duì)node的事件機(jī)制不是很清楚职祷,這一部分只是我的猜測(cè))。如果沒(méi)有對(duì)'uncaughtException'事件進(jìn)行處理诈嘿,node進(jìn)程就會(huì)被終止并輸出上文所看到的錯(cuò)誤信息堪旧。

因此削葱,如果要在不傳遞回調(diào)函數(shù)的情況下忽略可能發(fā)生的網(wǎng)絡(luò)錯(cuò)誤奖亚,應(yīng)當(dāng)使用下面的代碼

'use strict';

const request = require('request');

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

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

老實(shí)說(shuō),上面的代碼還不如寫(xiě)成

'use strict';

const request = require('request');

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

我的目的只在于請(qǐng)求服務(wù)端API而不在意失敗析砸,因此最終的代碼如下

'use strict';

const request = require('request');

request('http://127.0.0.1:8000/', function () {});
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末昔字,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌作郭,老刑警劉巖陨囊,帶你破解...
    沈念sama閱讀 216,591評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異夹攒,居然都是意外死亡蜘醋,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門咏尝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)压语,“玉大人,你說(shuō)我怎么就攤上這事编检√ナ常” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,823評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵允懂,是天一觀的道長(zhǎng)厕怜。 經(jīng)常有香客問(wèn)我,道長(zhǎng)蕾总,這世上最難降的妖魔是什么粥航? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,204評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮生百,結(jié)果婚禮上躁锡,老公的妹妹穿的比我還像新娘。我一直安慰自己置侍,他們只是感情好映之,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著蜡坊,像睡著了一般杠输。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上秕衙,一...
    開(kāi)封第一講書(shū)人閱讀 51,190評(píng)論 1 299
  • 那天蠢甲,我揣著相機(jī)與錄音,去河邊找鬼据忘。 笑死鹦牛,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的勇吊。 我是一名探鬼主播曼追,決...
    沈念sama閱讀 40,078評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼汉规!你這毒婦竟也來(lái)了礼殊?” 一聲冷哼從身側(cè)響起驹吮,我...
    開(kāi)封第一講書(shū)人閱讀 38,923評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎晶伦,沒(méi)想到半個(gè)月后碟狞,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,334評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡婚陪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評(píng)論 2 333
  • 正文 我和宋清朗相戀三年族沃,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片泌参。...
    茶點(diǎn)故事閱讀 39,727評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡竭业,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出及舍,到底是詐尸還是另有隱情未辆,我是刑警寧澤,帶...
    沈念sama閱讀 35,428評(píng)論 5 343
  • 正文 年R本政府宣布锯玛,位于F島的核電站咐柜,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏攘残。R本人自食惡果不足惜拙友,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望歼郭。 院中可真熱鬧遗契,春花似錦、人聲如沸病曾。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,672評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)泰涂。三九已至鲫竞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間逼蒙,已是汗流浹背从绘。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,826評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留是牢,地道東北人僵井。 一個(gè)月前我還...
    沈念sama閱讀 47,734評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像驳棱,于是被迫代替她去往敵國(guó)和親批什。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容