成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

Node 錯誤處理之挖坑系列

afishhhhh / 1988人閱讀

摘要:一中的對象包含了錯誤的具體信息,包括錯誤堆棧等。不源碼了,特別簡單,自己去一下。

一. Error

????JS 中的 Error 對象. 包含了錯誤的具體信息,包括 name、message、錯誤堆棧 stack 等??梢砸?new Error 方式創(chuàng)建實例拋出,或調(diào)用 Error.captureStackTrace 為已有對象添加 stack 錯誤堆棧信息 而后拋出

二. 錯誤拋出幾種方式

Throw
Javascript 拋出的異常,是以 throw 方法拋出,未必都是 Error 的實例,但通過 nodeJs 或者 js 運行時發(fā)生的錯誤,都是 Error 的實例

EventEmitter
Nodejs 形式的錯誤回調(diào),大部分流 & 異步事件都衍生自 EventEmitter 類 || 實例,如 fs, process, stream 等

Process
程序運行過程中拋出的異常,或由底層庫拋出,或是運行中發(fā)生的一些 SyntaxError 之類

三. 錯誤捕獲幾種方式

try .. catch

常用的一種捕獲錯誤方式,瀏覽器 || node 環(huán)境均適用

缺點:只針對同步異常有效

    try {
        throw new Error("Something went wrong here")
    } catch (err) {
        console.log(err)
    }

EventEmitter

????由 Events 模塊提供的 EventEmitter 類,基于 Observer 模式做的 publish/subscribe,通過 .on("error", ...) || .addEventlistener("error", ...) 注冊 subscriber,.emit() 發(fā)布事件,但會有最大的 maxListener 的限制,可更改。
????不 show 源碼了,特別簡單,自己去 look 一下。如 koa 的 app 就是基于 EventEmitter 的擴展,因此可以通過監(jiān)聽 error

    class Koa extends EventEmitter {...}
    
    let app = new Koa()
    app.emit("error", ..)
    app.on("error", ...)

Process

Process 進程對象也是 EventEmitter 的實例,可通過如下兩事件監(jiān)聽 error

unhandledRejection
????promise 的回調(diào)報錯,可通過監(jiān)聽該事件 catch,但要注意由于 promise 的 rejection catched 不知道會在啥時候才發(fā)生,所以實際上可能在 unhandledRejection 事件觸發(fā)后才 catch 了這個信息,對應(yīng)有 rejectionHandled 事件監(jiān)聽,如下:

    process.on("rejectionHandled", p => {
        console.log("It has been handled")
    })
    
    process.on("unhandledRejection", (reason, p) => {
        console.log("Went here")
    })
    
    let test = new Promise((resolve, reject) => {
        let err = new Error("Just for a test")
        err.name = "TestError"
        reject(err)
    })
    
    setTimeout(() => {
        test.catch(err => {
            console.log("Excample work!")
            console.log(err)
        })
    }, 10000)

    // 打印出來的信息順序是:
    // Went here
    // It has been handled
    // Excample work!
    // { TestError: Just for a test
    // ....(stack message here) }

(承上)
uncaughtException
????其余 js 運行中發(fā)生 || 拋出的未捕獲錯誤,均可通過監(jiān)聽該事件解決,若不進行該事件的監(jiān)聽,發(fā)生異常時,會直接導(dǎo)致程序 crash
????但不建議用這種方式 catch,程序運行中的錯誤 更應(yīng)該是拋出來,所有的 error 都 catch 的話,豈不是程序都可以看成無 bug 了
????but 在打錯誤日志的時候是需要 catch 上報日志的,但是在上報完后,需要繼續(xù)把 error throw,對于 uncaughtException callback 中拋出的異常不會再捕獲,而是以非 0 的狀態(tài)碼 exit

    // Promise Rejection
    process.on("unhandledRejection", err => {
        process.nextTick(() => { throw err }))
    })
    // 終極 boss
    process.on("uncaughtException", err => {...})
};
四.小結(jié)

以上以一張圖為總結(jié):

五. 源碼解讀

補充之前沒補充完的內(nèi)容,下圖為 node 中對于 process 的初始化等系列流程

node.cc 其實是 node 運行主要的文件,其中定義了三個重載函數(shù) Start,調(diào)用順序為 3 → 2 → 1,每個函數(shù)參數(shù)不同處理不同的邏輯;

isolate->AddMessageListener 的監(jiān)聽事件 OnMessage 會在 js 運行發(fā)生錯誤時觸發(fā),嗯,是的,只有 error 才會傳遞 ;這很好的解釋了為什么 process 監(jiān)聽 uncaughtException 就可以監(jiān)聽到所有的拋出的非 promise 異常;

OnMessage 調(diào)用了 FatalException 函數(shù),F(xiàn)atalException 引用 process._fatalException 并傳入 error (env 是 env.h 中聲明的 Environment 類實例,fatal_exception_string 也是其中定義的,返回值為 "_fatalException");
以下為 FatalException 函數(shù)的部分內(nèi)容

void FatalException(Isolate* isolate,
                    Local error,
                    Local message) {
...(省略)
  Local fatal_exception_string = env->fatal_exception_string(); // "_fatalException"
  Local fatal_exception_function =
      process_object->Get(fatal_exception_string).As();
...(省略)
if (exit_code == 0) {
    TryCatch fatal_try_catch(isolate); // 調(diào)用 v8::TryCatch 
    
    // Do not call FatalException when _fatalException handler throws
    fatal_try_catch.SetVerbose(false); // 關(guān)鍵點

    // this will return true if the JS layer handled it, false otherwise
    Local caught =
        fatal_exception_function->Call(process_object, 1, &error); // 運行 process._fatalException 函數(shù)

    if (fatal_try_catch.HasCaught()) { // 捕獲錯誤
      // the fatal exception function threw, so we must exit
      ReportException(env, fatal_try_catch);
      exit_code = 7;
    }

    if (exit_code == 0 && false == caught->BooleanValue()) {
      ReportException(env, error, message);
      exit_code = 1;
    }
  }
...(省略)
}

在調(diào)用 _fatalException 函數(shù)前,先調(diào)用 v8::TryCatch::setVerbose 把 verbose 設(shè)置為 false,則運行時拋出的異常就不會再觸發(fā) FatalException ;在捕獲到運行錯誤后,把 exit_code 設(shè)為 7,并返回;這就解釋了 為什么在 uncaughtException 時拋出的異常不會再重新觸發(fā)回調(diào),要知道 EventEmitter 可沒幫你做這樣的事情

_fatalException 在觸發(fā) "uncaughtException" 事件前其實是會優(yōu)先檢查 domain 是否存在,當 domain 不存在時才會調(diào)用 uncaughtException 的,但 domain 這個 api 已經(jīng)被廢除了,也就不累述了

unhandledRejection 事件的觸發(fā)整體思路也差不多,首先會調(diào)用 SetupPromises 初始化,然后調(diào)用 v8::Isolate::SetPromiseRejectCallback 進行監(jiān)聽 ... 并且跟 uncaughtException 不同的是 unhandledRejection 的觸發(fā)只會打印 warning 并不會把整個程序給 crash 了

六. END

若本文有誤,歡迎隨時指正

參考鏈接
V8 API Reference Guide

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/91927.html

相關(guān)文章

  • 關(guān)于前端接口測試的探索和挖坑

    摘要:本文主要關(guān)注的是接口測試。所謂接口測試,就是檢查系統(tǒng)提供的接口是否符合事先撰寫的接口文檔。作為接口測試的解決方案,我們必須具備通用性與易用性。 開始 最近幾年,前端測試漸漸被人重視,相關(guān)的框架和方法已經(jīng)比較成熟。斷言庫有should, expect, chai。 單元測試框架有mocha, jasmine, Qunit。 模擬瀏覽器測試環(huán)境有Phantomjs, Slimerjs。 集...

    Crazy_Coder 評論0 收藏0
  • 關(guān)于前端接口測試的探索和挖坑

    摘要:本文主要關(guān)注的是接口測試。所謂接口測試,就是檢查系統(tǒng)提供的接口是否符合事先撰寫的接口文檔。作為接口測試的解決方案,我們必須具備通用性與易用性。 開始 最近幾年,前端測試漸漸被人重視,相關(guān)的框架和方法已經(jīng)比較成熟。斷言庫有should, expect, chai。 單元測試框架有mocha, jasmine, Qunit。 模擬瀏覽器測試環(huán)境有Phantomjs, Slimerjs。 集...

    zxhaaa 評論0 收藏0
  • node學(xué)習(xí)系列基礎(chǔ)(二)

    摘要:由于這種特性,某一個任務(wù)的后續(xù)操作,往往采用回調(diào)函數(shù)的形式進行定義。另外,回調(diào)函數(shù)本身的第一個參數(shù),約定為上一步傳入的錯誤對象。這種寫法有一個很大的好處,就是說只要判斷回調(diào)函數(shù)的第一個參數(shù),就知道有沒有出錯,如果不是,就肯定出錯了。 REPL環(huán)境 在命令行鍵入node命令,后面沒有文件名,就進入一個Node.js的REPL環(huán)境(Read–eval–print loop,讀取-求值-輸出...

    zhaot 評論0 收藏0
  • 迪米特法則

    摘要:個人博客原文迪米特法則設(shè)計模式六大原則之五迪米特法則。老師便給同學(xué)們講解了這個例子,讓學(xué)生感受一番迪米特法則。總結(jié)迪米特法則主要講述的觀點是高內(nèi)聚低耦合。 個人博客原文:迪米特法則 showImg(https://segmentfault.com/img/remote/1460000017779272?w=960&h=520); 設(shè)計模式六大原則之五:迪米特法則。 簡介 姓名:迪米特法...

    OnlyMyRailgun 評論0 收藏0
  • 深入了解JavaScript 中的For循環(huán)詳解

    摘要:將品牌的標價全部加蘇南的專欄交流公眾號不會對空數(shù)組進行檢測。方法用于調(diào)用數(shù)組的每個元素,并將元素傳遞給回調(diào)函數(shù)。 showImg(https://segmentfault.com/img/bVblSSO?w=1008&h=298); 前言: ? 今天我想分享一個有關(guān)于循環(huán)篩選的知識點,也許是前端小白的你首先想到的是用for循環(huán)做篩選,但我這種小菜鳥想到的就是map(工作中很喜歡...

    linkin 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<