最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • nodejs中错误捕获

    正文概述 掘金(healerhe)   2021-03-20   447

    nodejs中错误捕获

    在捕获NodeJS错误前,我们首先得知道NodeJs的错误由哪些以及怎么抛出这些错误

    NodeJS的错误类型

    一般来说,我们将错误简单的分为两种类型:操作错误、编码错误。

    操作错误

    写代码的时候都会处理一些常见的操作错误,例如JSON.parse总是会和try...catch一起,例如网络故障、远程服务器返回500等。这些错误并非bug。

    处理操作错误

    1. 对于明确的操作错误类型,直接处理掉。
    2. 对于预料之外你不知道如何处理的错误,比较好的方式是记录error并crash,传递合适的错误信息给客户端。

    编码错误

    写代码的时候都会处理一些常见的操作错误,例如JSON.parse总是会和try...catch一起,例如网络故障、远程服务器返回500等。这些错误并非bug。

    处理编码错误

    最好的方式是立即crash。

    NodeJS暴露错误的方式

    一般通过throw、callback(err, result)错误回调函数、Event Emitter, domain暴露错误。

    throw用法

    throw new Error(name, message);
    

    注意

    • 所有的erorr都使用Error对象(或者基于Error类的扩展)

    • 所有的error都应该提供name和message属性,并且stack也应该准确可用。

    • 使用name属性来区分错误类型

    例如RangeError、TypeError。 不要为每种错误取个名字,例如定义InvalidHostnameError、InvalidIpAddressError这种来表示具体的错误,对于这种错误可以统一用InvalidArgumentError表示错误类型,然后在详细描述里补充更多信息。

    示例

    class InvalidArgumentError extends Error{
        constructor(message) {
            super();
            this.name = "InvalidArgumentError";
            this.message = message;
        }
    }
    throw new InvalidArgumentError("testError");
    //控制台输出
    Uncaught InvalidArgumentError: testError
        at <anonymous>:8:7
    

    callback用法

    一般用于异步函数对于错误处理的回调函数

    callback(err, result)
    

    EventEmitter用法

    复杂场景中可以返回一个EventEmitter对象,代替使用callback。

    events 模块只提供了一个对象: events.EventEmitter。EventEmitter 的核心就是事件触发与事件监听器功能的封装

    //event.js 文件
    var EventEmitter = require('events').EventEmitter; 
    var event = new EventEmitter(); 
    event.on('some_event', function() {  //事件注册
        console.log('some_event 事件触发'); 
    }); 
    setTimeout(function() { 
        event.emit('some_event');  //事件触发
    }, 1000); 
    

    domain

    domain和全局的异常捕获主要是为了发现和处理未预料到的编码错误 Domain(域) 简化异步代码的异常处理,可以捕捉处理try catch无法捕捉的异常。

    var domain = require("domain")
    

    domain模块,把处理多个不同的IO的操作作为一个组。注册事件和回调到domain,当发生一个错误事件或抛出一个错误时,domain对象会被通知,不会丢失上下文环境,也不导致程序错误立即退出,与process.on('uncaughtException')不同。

    Domain 模块可分为隐式绑定和显式绑定:

    隐式绑定: 把在domain上下文中定义的变量,自动绑定到domain对象

    显式绑定: 把不是在domain上下文中定义的变量,以代码的方式绑定到domain对象

    示例

    var EventEmitter = require("events").EventEmitter;
    var domain = require("domain");
    
    var emitter1 = new EventEmitter();
    
    // 创建域
    var domain1 = domain.create();
    domain1.on('error', function(err){
       console.log("domain1 处理这个错误 ("+err.message+")");
    });
    // 显式绑定
    domain1.add(emitter1);
    emitter1.emit('error',new Error('通过监听器来处理')); // domain1 处理这个错误 (通过 domain1 处理)
    
    var domain2 = domain.create();
    domain2.on('error', function(err){
       console.log("domain2 处理这个错误 ("+err.message+")");
    });
    // 隐式绑定
    domain2.run(function(){
       var emitter2 = new EventEmitter();
       emitter2.emit('error',new Error('通过 domain2 处理'));  // domain2 处理这个错误 (通过 domain2 处理)
    });
    
    
    domain1.remove(emitter1);
    emitter1.emit('error', new Error('转换为异常,系统将崩溃!'));//转换为异常,系统将崩溃!
    

    暴露错误的基本原则:

    1. 同步的函数里,使用throw。使用者使用try...catch即可捕获错误。

    2. 异步函数里,更常用的方式是使用callback(err, result)的方式。

    3. 在更复杂的场景里,可以返回一个EventEmitter对象,代替使用callback。使用者可以监听emitter对象的 error事件。 例如读取一个数据流,我们可能会同时使用 req.on('data')、req.on('error')、req.on('timeout') 。

    4. 一般用于发现和处理未预料到的编码错误。

    NodeJS错误捕获的方式

    1. try catch

    通常用于捕获throw抛出的错误

    1. callback(err, result)回调函数处理

    2. Emitter.on的回调函数

    on注册了事件和回调函数, 并且在emit触发事件后会执行回调函数,以达到捕获错误的解决方式。

    1. process.on("error", function(err){})

    错误异常有两种场景的出现:

    一种是代码运行中throw new error没有被捕获,另一种是Promise的失败回调函数,没有对应的reject回调函数处理,针对这两种情况Nodejs都有默认的统一处理方式,就是给整个进程process对象监听相应的错误事件。

    
    process.on('uncaughtException',function(err){}) //监听未捕获的异常
    
    process.on('unhandledRejection',function(err,promise){}) //监听Promise没有被捕获的失败函数
    
    1. express

    express作为nodejs比较常用的框架,其实nodejs自己也有一定的异常错误捕获机制

    // Express' errorHandler
    function errorHandler(err, req, res, next) {
    console.error(err.stack);
    }
    app.use(errorHandler);
    

    总结

    1. 区分错误类型,是可预见的还是不可避免的,是操作错误还是bug。

    2. 操作错误应该被处理。编码错误不应该被处理(全局处理并记录)。

    3 一个函数可能产生的操作错误,只应该使用同步(throw)或者异步一种方式。一般来说,在nodejs中,同步函数导致的操作错误是比较少见的,使用try...catch会很少,常见的是用户输入验证如JSON、解析等。

    1. 一个函数的参数、类型、预期错误、如何捕获都应该是明确的。

    2. 缺少参数、参数无效都属于编码错误,应该直接抛出异常(throw)。

    3. 使用标准的Error类和标准属性。使用独立的属性,添加尽可能多的附加信息,尽可能使用通用的属性名称。

    4. 不要尝试用try...catch去捕获一个异步函数的错误,这样会什么也得不到。

    8、如果不是产生错误,不要使用throw。


    起源地下载网 » nodejs中错误捕获

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元