精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

聊聊Nodejs的錯誤處理

開發 前端
當操作系統收到一個發給該socket的rst包的時候會執行tcp_reset,我們看到當socket處于發送syn包等待ack的時候,如果收到一個fin包,則會設置錯誤碼為ECONNREFUSED。我們輸出的正是這個錯誤碼。

[[392980]]

本文轉載自微信公眾號「編程雜技」,作者theanarkh。轉載本文請聯系編程雜技公眾號。  

本文以連接錯誤ECONNREFUSED為例,看看nodejs對錯誤處理的過程。

假設我們有以下代碼

  1. const net = require('net'); 
  2.  
  3. net.connect({port: 9999}) 

如果本機上沒有監聽9999端口,那么我們會得到以下輸出。

  1. events.js:170   
  2.        throw er; // Unhandled 'error' event   
  3.        ^   
  4.     
  5.  Error: connect ECONNREFUSED 127.0.0.1:9999   
  6.      at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1088:14)   
  7.  Emitted 'error' event at:   
  8.      at emitErrorNT (internal/streams/destroy.js:91:8)   
  9.      at emitErrorAndCloseNT (internal/streams/destroy.js:59:3)   
  10.      at processTicksAndRejections (internal/process/task_queues.js:81:17)  

我們簡單看一下connect的調用流程。

  1. const req = new TCPConnectWrap();   
  2. req.oncomplete = afterConnect;   
  3. req.address = address;   
  4. req.port = port;   
  5. req.localAddress = localAddress;   
  6. req.localPort = localPort;   
  7. // 開始三次握手建立連接   
  8. err = self._handle.connect(req, address, port);  

接著我們看一下C++層connect的邏輯

  1. err = req_wrap->Dispatch(uv_tcp_connect,   
  2.                 &wrap->handle_,   
  3.                 reinterpret_cast(&addr),   
  4.                 AfterConnect);  

C++層直接調用Libuv的uv_tcp_connect,并且設置回調是AfterConnect。接著我們看libuv的實現。

  1. do {   
  2.     errno = 0;   
  3.     // 非阻塞調用   
  4.     r = connect(uv__stream_fd(handle), addr, addrlen);   
  5.   } while (r == -1 && errno == EINTR);   
  6.   // 連接錯誤,判斷錯誤碼   
  7.   if (r == -1 && errno != 0) {   
  8.     // 還在連接中,不是錯誤,等待連接完成,事件變成可讀   
  9.     if (errno == EINPROGRESS)   
  10.       ; /* not an error */   
  11.     else if (errno == ECONNREFUSED)   
  12.       // 連接被拒絕   
  13.       handle->delayed_error = UV__ERR(ECONNREFUSED);   
  14.     else   
  15.       return UV__ERR(errno);   
  16.   }   
  17.   uv__req_init(handle->loop, req, UV_CONNECT);   
  18.   req->cb = cb;   
  19.   req->handle = (uv_stream_t*) handle;   
  20.   QUEUE_INIT(&req->queue);   
  21.   // 掛載到handle,等待可寫事件   
  22.   handle->connect_req = req;   
  23. uv__io_start(handle->loop, &handle->io_watcher, POLLOUT);

我們看到Libuv以異步的方式調用操作系統,然后把request掛載到handle中,并且注冊等待可寫事件,當連接失敗的時候,就會執行uv__stream_io回調,我們看一下Libuv的處理(uv__stream_io)。

  1. getsockopt(uv__stream_fd(stream),   
  2.                SOL_SOCKET,   
  3.                SO_ERROR,   
  4.                &error,   
  5.                &errorsize);   
  6. error = UV__ERR(error);   
  7. if (req->cb)   
  8.     req->cb(req, error); 

獲取錯誤信息后回調C++層的AfterConnect。

  1. Localargv[5] = {   
  2.    Integer::New(env->isolate(), status),   
  3.    wrap->object(),   
  4.    req_wrap->object(),   
  5.    Boolean::New(env->isolate(), readable),   
  6.    Boolean::New(env->isolate(), writable)   
  7.  };   
  8.    
  9.  req_wrap->MakeCallback(env->oncomplete_string(), arraysize(argv), argv);   

接著調用JS層的oncomplete回調。

  1. const ex = exceptionWithHostPort(status,   
  2.                                  'connect',   
  3.                                  req.address,   
  4.                                  req.port,   
  5.                                  details);   
  6. if (details) {   
  7.   ex.localAddress = req.localAddress;   
  8.   ex.localPort = req.localPort;   
  9. }   
  10. // 銷毀socket   
  11. self.destroy(ex); 

exceptionWithHostPort構造錯誤信息,然后銷毀socket并且以ex為參數觸發error事件。我們看看uvExceptionWithHostPort的實現。

  1. function uvExceptionWithHostPort(err, syscall, address, port) {   
  2.   const [ code, uvmsg ] = uvErrmapGet(err) || uvUnmappedError;   
  3.   const message = `${syscall} ${code}: ${uvmsg}`;   
  4.   let details = '';   
  5.    
  6.   if (port && port > 0) {   
  7.     details = ` ${address}:${port}`;   
  8.   } else if (address) {   
  9.     details = ` ${address}`;   
  10.   }   
  11.   const tmpLimit = Error.stackTraceLimit;   
  12.   Error.stackTraceLimit = 0;   
  13.   const ex = new Error(`${message}${details}`);   
  14.   Error.stackTraceLimit = tmpLimit;   
  15.   ex.code = code;   
  16.   ex.errno = err;   
  17.   ex.syscall = syscall;   
  18.   ex.address = address;   
  19.   if (port) {   
  20.     ex.port = port;   
  21.   }   
  22.   // 獲取調用棧信息但不包括當前調用的函數uvExceptionWithHostPort,注入stack字段到ex中   
  23.   Error.captureStackTrace(ex, excludedStackFn || uvExceptionWithHostPort);   
  24.   return ex;   
  25. }   

我們看到錯誤信息主要通過uvErrmapGet獲取

  1. unction uvErrmapGet(name) {   
  2.    uvBinding = lazyUv();   
  3.    if (!uvBinding.errmap) {   
  4.      uvBinding.errmap = uvBinding.getErrorMap();   
  5.    }   
  6.    return uvBinding.errmap.get(name);   
  7.  }   
  8.     
  9.  function lazyUv() {   
  10.    if (!uvBinding) {   
  11.      uvBinding = internalBinding('uv');   
  12.    }   
  13.    return uvBinding;   
  14.  } 

繼續往下看,uvErrmapGet調用了C++層的uv模塊的getErrorMap。

  1. void GetErrMap(const FunctionCallbackInfo& args) {   
  2.   Environment* env = Environment::GetCurrent(args);   
  3.   Isolate* isolate = env->isolate();   
  4.   Localcontext = env->context();   
  5.    
  6.   Local 
  7.   // 從per_process::uv_errors_map中獲取錯誤信息   
  8.   size_t errors_len = arraysize(per_process::uv_errors_map);   
  9.   // 賦值   
  10.   for (size_t i = 0; i < errors_len; ++i) {   
  11.      // map的鍵是 uv_errors_map每個元素中的value,值是name和message 
  12.     const auto& error = per_process::uv_errors_map[i];   
  13.     Localarr[] = {OneByteString(isolate, error.name),   
  14.                           OneByteString(isolate, error.message)};  
  15.     if (err_map   
  16.             ->Set(context,   
  17.                   Integer::New(isolate, error.value),   
  18.                   Array::New(isolate, arr, arraysize(arr)))   
  19.             .IsEmpty()) {   
  20.       return;   
  21.     }   
  22.   }   
  23.    
  24.   args.GetReturnValue().Set(err_map);   

我們看到錯誤信息存在per_process::uv_errors_map中,我們看一下uv_errors_map的定義。

  1. struct UVError { 
  2.   int value; 
  3.   const charname
  4.   const char* message; 
  5. }; 
  6.  
  7. static const struct UVError uv_errors_map[] = {   
  8. #define V(name, message) {UV_##name, #name, message},   
  9.     UV_ERRNO_MAP(V)   
  10. #undef V   
  11. };   

UV_ERRNO_MAP宏展開后如下

  1. {UV_E2BIG, "E2BIG""argument list too long"},   
  2. {UV_EACCES, "EACCES""permission denied"},   
  3. {UV_EADDRINUSE, "EADDRINUSE""address already in use"},   
  4. ……  

所以導出到JS層的結果如下

  1. {   
  2.   // 鍵是一個數字,由Libuv定義,其實是封裝了操作系統的定義 
  3.   UV_ECONNREFUSED: ["ECONNREFUSED""connection refused"],     
  4.   UV_ECONNRESET: ["ECONNRESET""connection reset by peer"]    
  5.   ...    
  6. }  

Node.js最后會組裝這些信息返回給調用方。這就是我們輸出的錯誤信息。那么為什么會是ECONNREFUSED呢?我們看一下操作系統對于該錯誤碼的邏輯。

  1. static void tcp_reset(struct sock *sk)   
  2. {   
  3.     switch (sk->sk_state) {   
  4.         case TCP_SYN_SENT:   
  5.             sk->sk_err = ECONNREFUSED;   
  6.             break;   
  7.          // ... 
  8.     }   
  9.    
  10. }  

當操作系統收到一個發給該socket的rst包的時候會執行tcp_reset,我們看到當socket處于發送syn包等待ack的時候,如果收到一個fin包,則會設置錯誤碼為ECONNREFUSED。我們輸出的正是這個錯誤碼。

責任編輯:武曉燕 來源: 編程雜技
相關推薦

2021-04-29 09:02:44

語言Go 處理

2024-03-27 08:18:02

Spring映射HTML

2014-11-17 10:05:12

Go語言

2023-12-26 22:05:53

并發代碼goroutines

2022-11-16 08:41:43

2010-06-01 16:14:04

2009-08-05 16:04:50

2023-10-28 16:30:19

Golang開發

2009-06-19 16:20:14

ASP.NET錯誤處理

2023-10-08 20:31:18

React

2016-09-07 20:28:17

MySQL存儲數據庫

2016-08-19 10:41:42

Swift 2錯誤

2017-03-08 08:57:04

JavaScript錯誤堆棧

2011-05-25 10:26:42

ora-02069錯誤

2015-08-19 14:11:56

SQL Server錯誤處理

2017-04-06 14:40:29

JavaScript錯誤處理堆棧追蹤

2025-02-10 09:49:00

2021-09-13 07:53:31

Go錯誤處理

2025-03-31 00:29:44

2020-08-20 10:16:56

Golang錯誤處理數據
點贊
收藏

51CTO技術棧公眾號

91精品电影| yiren22亚洲综合| av激情综合网| 国产精品成熟老女人| 天堂а√在线中文在线鲁大师| 青青草国产一区二区三区| 一区二区三区成人| 四虎影院一区二区三区 | 91九色02白丝porn| 激情五月五月婷婷| 免费国产在线观看| 国产精品456| 国产激情视频一区| 国产精彩视频在线| 99国产**精品****| 亚洲免费中文字幕| 无码国产精品一区二区高潮| 日韩av首页| 午夜精品一区二区三区电影天堂| 无码免费一区二区三区免费播放 | 中文字幕一区二区三区四区免费看| 欧美日韩福利| 日韩一级裸体免费视频| 制服丝袜第二页| 中文字幕区一区二区三| 欧美日韩的一区二区| 国产综合中文字幕| jizz性欧美10| 国产精品私房写真福利视频| 久久青青草综合| www.热久久| 麻豆成人久久精品二区三区红| 青青草原一区二区| 天堂网一区二区三区| 国产精品a久久久久| 久久综合网hezyo| av片在线免费看| 九九久久婷婷| 亚洲老头老太hd| 欧美在线一级片| 911亚洲精品| 欧美videos中文字幕| 国产农村妇女精品久久| 亚洲成人高清| 欧美日本国产视频| 不卡的在线视频| 成人国产网站| 欧美日韩精品一区二区三区 | 蜜桃精品视频| 制服丝袜一区二区三区| www.cao超碰| 91九色成人| 91精彩视频在线观看| 激情偷乱视频一区二区三区| 国产精品精品视频| 无码人妻丰满熟妇精品区| 老鸭窝亚洲一区二区三区| 日韩美女福利视频| 手机av免费观看| 日韩成人免费电影| 国产在线高清精品| 国产精品无码免费播放| 国产精品白丝av| 国产精品大全| 天天色综合久久| 久久综合九色综合欧美就去吻 | 国产成人极品视频| 久久久久久无码精品大片| 日韩成人av影视| 国产日韩欧美在线播放| h片在线免费看| 成人激情校园春色| 欧美三日本三级少妇三99| 成人综合影院| 亚洲欧美日韩中文字幕一区二区三区 | 精品久久久久久久久久久| 欧美一区二区中文字幕| 成人黄色免费短视频| 欧美三级三级三级爽爽爽| 天天做天天干天天操| 18国产精品| 亚洲毛片在线看| 懂色av蜜臀av粉嫩av永久| 欧美国产91| 欧洲中文字幕国产精品| 一区二区美女视频| 懂色av一区二区三区免费看| 久久精品人人做人人爽电影| 亚洲免费视频一区二区三区| 一区二区三区四区视频精品免费| 尤物av无码色av无码| 福利视频一区| 亚洲国产精品99久久| 国产真实乱人偷精品人妻| 亚洲九九在线| 日韩av电影中文字幕| 国产精品久久久久毛片| xnxx国产精品| 男女爱爱视频网站| 在线免费日韩片| 日韩午夜在线影院| 国产人妻一区二区| 欧美三区美女| 国产精品视频区| 日本成人动漫在线观看| 亚洲欧洲精品成人久久奇米网| 日韩伦理在线免费观看| a成人v在线| 日韩国产高清视频在线| 放荡的美妇在线播放| 日韩中文欧美在线| 国产一区免费在线| 18+视频在线观看| 在线亚洲欧美专区二区| 精品久久久久一区二区| 999久久久91| 国产mv免费观看入口亚洲| 丰满少妇被猛烈进入| 日本一区二区三区国色天香 | 美日韩一级片在线观看| 精品综合久久| 国产精品蜜臀| 欧美一二三区精品| 国产精品麻豆免费版现看视频| 日韩视频二区| 高清国产一区| 欧美家庭影院| 欧美一卡2卡3卡4卡| jizzjizz日本少妇| 日韩电影一区二区三区四区| 久久综合福利| 久久影院午夜精品| 亚洲第一福利网站| 69精品久久久| 成人美女视频在线观看18| 中文字幕人成一区| 亚洲精品一区av| 日韩在线观看精品| 在线观看色网站| 国产精品毛片高清在线完整版| 亚洲性生活网站| 国产精品毛片一区二区| 日韩区欧美区| 成人看片网站| 日韩欧美亚洲一区二区| 一区二区国产精品精华液| 日本中文字幕不卡| 日韩久久久久久久久久久久久| 在线观看特色大片免费视频| 日韩激情av在线免费观看| 国产精品第九页| 成人激情免费电影网址| 福利视频免费在线观看| 丁香一区二区| 97在线免费观看视频| 天天干天天舔天天射| 亚洲国产精品久久久久婷婷884 | 在线播放国产精品| 亚洲精品一区二三区| 久久久久国产免费免费| 一本色道无码道dvd在线观看| 久久99蜜桃| 国产精品视频色| 国产乱色在线观看| 日韩欧美在线影院| 久久久精品99| 91老师片黄在线观看| 欧美精品无码一区二区三区| 欧美手机视频| 91免费欧美精品| 欧美日韩色网| 国产视频久久久久| 波多野结衣在线观看视频| 中文字幕精品一区二区三区精品| 亚洲另类第一页| 综合日韩在线| 国产一区二区黄色| 黄色精品视频| 欧美精品中文字幕一区| 熟妇高潮一区二区三区| 日韩欧美999| 99自拍偷拍视频| 国产大陆精品国产| 动漫av网站免费观看| 国产中文精品久高清在线不| 91色在线观看| 久草在线资源福利站| 丝袜亚洲另类欧美重口| av中文字幕免费在线观看| 亚洲高清免费观看 | 精品在线91| 91免费视频国产| 欧美电影免费观看高清完整| www.亚洲免费视频| 日韩中文字幕综合| 欧美性色aⅴ视频一区日韩精品| 国产精品99久久久久久成人| 91亚洲国产成人精品一区二三| 北条麻妃在线视频| 亚洲一区欧美| 欧美日韩精品久久| 亚洲一区二区三区免费| 国产精品久久久久久久久久久久久 | 日韩欧美国产另类| 一区二区三区日韩欧美| 五月天精品视频| 丁香六月久久综合狠狠色| 五月婷婷狠狠操| 99国产精品久久久久久久成人热| 一区二区三区四区| 中文字幕伦av一区二区邻居| aa成人免费视频| 国产精品99| 久久久久免费视频| 日本在线观看视频| 日韩精品在线观看一区二区| 99热这里是精品| 欧美日韩综合在线免费观看| 日本免费观看视| 一区二区在线观看av| 国产欧美小视频| 久久久一区二区| 黄色av网址在线观看| 国产乱子轮精品视频| 精品理论电影在线| 欧美撒尿777hd撒尿| 国产稀缺真实呦乱在线| 国产精品色婷婷| 欧美做受喷浆在线观看| 国产精品自拍三区| 久热精品在线观看视频| 久久aⅴ乱码一区二区三区| 国产成人永久免费视频| 精品美女视频| 日本一区二区三区www| 日韩精品导航| 精品无码久久久久国产| 6080成人| 国产一区二区三区奇米久涩| 91麻豆精品激情在线观看最新| 91在线高清免费观看| 精品久久毛片| 国产精品露脸av在线| 成人日韩在线观看| 欧美中文在线视频| 亚洲欧洲美洲av| 热草久综合在线| 国产精品专区免费| 庆余年2免费日韩剧观看大牛| 9i看片成人免费高清| 秋霞av国产精品一区| 午夜欧美巨大性欧美巨大| 国产999在线| 91久久久久久白丝白浆欲热蜜臀| 国产精品激情自拍| 日韩三区四区| 91久热免费在线视频| 免费一级欧美在线大片| 动漫3d精品一区二区三区 | 欧美日韩免费网站| 国产成人在线免费视频| 欧美视频二区36p| 欧美一区免费看| 精品视频免费在线| 国产精品亚洲欧美在线播放| 日韩一区二区三区视频| 亚洲国产精品欧美久久| 亚洲精品久久久久久久久久久久 | 久久在线观看| 国产精品久久久久久久久久久久冷| 成人h动漫精品一区二区器材| 精品国产福利| 成人看的视频| 大片在线观看网站免费收看| 在线播放精品| 黄色国产小视频| 国产一区二区免费在线| 欧美肉大捧一进一出免费视频| 久久久久久久综合| 国产精品成人69xxx免费视频| 一级精品视频在线观看宜春院| 国产精品999在线观看| 欧美又粗又大又爽| 精品国产99久久久久久宅男i| 亚洲精品国产精品乱码不99按摩 | 狠狠操狠狠干视频| 成人97人人超碰人人99| 久久精品三级视频| 亚洲精品免费在线播放| 神马久久久久久久| 日韩小视频在线观看专区| 欧洲成人av| 欧美精品性视频| 51一区二区三区| 国产欧美综合精品一区二区| 99精品综合| 色综合av综合无码综合网站| 国产一区二区三区日韩| 国产在线观看h| 亚洲午夜在线观看视频在线| 在线观看亚洲一区二区| 亚洲国产三级网| 国产激情在线视频| 国产精品高精视频免费| 国产精品久久久网站| 日韩 欧美 自拍| 青青草视频一区| 免费人成又黄又爽又色| 午夜av区久久| 亚洲av无码专区在线| 俺去了亚洲欧美日韩| 欧美亚洲韩国| 精品国产日本| 欧美日本三区| 手机在线免费毛片| 国产精品色一区二区三区| 免费无码国产精品| 亚洲精品第一页| 97蜜桃久久| 国产精品视频免费一区| 一区二区三区四区日韩| 亚洲欧美日韩三级| 国产精品美女久久久久高潮| 天天干天天操天天操| 亚洲精品色婷婷福利天堂| av资源新版天堂在线| 99三级在线| 欧美日韩精品| 少妇愉情理伦片bd| 亚洲欧美综合网| 一级特黄aaa大片| 中文字幕日韩精品在线| 日韩国产网站| 欧美在线日韩精品| 久久尤物视频| 精品成人无码一区二区三区| 色乱码一区二区三区88| 日本不卡免费播放| 日本高清不卡在线| 香蕉久久99| 国产精品wwwww| 国产丝袜欧美中文另类| 国产成人a v| 色综合伊人色综合网| 欧美电影在线观看网站| 亚洲日本欧美在线| 国产自产2019最新不卡| 欧美黑人猛猛猛| 精品日韩99亚洲| av在线私库| 欧美精品在线一区| 视频一区免费在线观看| 日韩精品电影一区二区三区| 欧美日韩精品免费观看视频| 日本三级视频在线播放| 亚洲va男人天堂| 国内精品亚洲| 九色porny自拍视频| 91国偷自产一区二区开放时间 | 中文字幕在线看高清电影| 91久久一区二区| 青青影院在线观看| 97欧洲一区二区精品免费| 日韩午夜高潮| 在线观看日本中文字幕| 欧美精品丝袜中出| 七七成人影院| 免费毛片一区二区三区久久久| 日韩激情av在线| 无码黑人精品一区二区| 亚洲精品在线三区| 希岛爱理一区二区三区av高清| 在线观看一区二区三区三州| 国产不卡视频在线观看| 国产在线观看黄色| 久久九九国产精品怡红院| 一区二区网站| 国产精品igao| 一区二区三区日韩在线观看| 美丽的姑娘在线观看免费动漫| 国产欧洲精品视频| 黄色日韩在线| 久久久久99精品成人| 精品国产一区二区亚洲人成毛片| 午夜裸体女人视频网站在线观看| 亚洲精品中文字幕乱码三区不卡| 国产成人免费视| 国产成人麻豆免费观看| 欧美乱妇高清无乱码| 免费精品国产| 日本中文字幕有码| 欧美性欧美巨大黑白大战| 天天干在线视频论坛| 日本午夜精品一区二区三区| 国产99久久精品| 一级α片免费看刺激高潮视频| 久久免费少妇高潮久久精品99| 日本黄色精品| 中国极品少妇videossexhd| 在线不卡中文字幕|