Node端异常捕获的实现方法

 更新时间:2022年06月26日 09:14:33   作者:程序媛徐婵  
本文主要介绍了Node端异常捕获的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

常见Node报错处理机制

try catch

try...catch是大家最常用的错误处理机制,Javascript语言内置的错误处理机制可以在检测到代码异常的时候直接进行捕获并处理。

function test() {
    try {
        throw new Error("error");
    } catch(e) {
        console.log(e);
    } finally {
        console.log("finally");
    }
}
   
test()

一般来说,throw 用于抛出异常,但是单纯从语言的角度,我们可以抛出任何值,也不一定是异常逻辑,但是为了保证语义清晰,不建议用 throw 表达任何非异常逻辑。try 语句用于捕获异常,用 throw 抛出的异常,可以在 try 语句的结构中被处理掉:try 部分用于标识捕获异常的代码段,catch 部分则用于捕获异常后做一些处理,而 finally 则是用于执行后做一些必须执行的清理工作。catch 结构会创建一个局部的作用域,并且把一个变量写入其中,需要注意,在这个作用域,不能再声明变量 e 了,否则会出错。在 catch 中重新抛出错误的情况非常常见,在设计比较底层的函数时,常常会这样做,保证抛出的错误能被理解。finally 语句一般用于释放资源,它一定会被执行,我们在前面的课程中已经讨论过一些 finally 的特征,即使在 try 中出现了 return,finally 中的语句也一定要被执行。

Node原生错误处理机制

大多数Node.js核心API都提供的是利用回调函数处理错误,之所以采用这种错误处理机制,是因为异步方法所产生的方法并不能简单地通过try...catch机制进行拦截。

const fs = require('fs');
  
function read() {
    fs.readFile("/some/file/does-not-exist", (err, data) => {
        if(err) {
            throw new Error("file not exist");
        }
        console.log(data);
    });
}
  
read();

Promise

Promise是用于处理异步调用的规范,由于 JavaScript 特殊的 EventLoop 机制,由 Promise 异步产生错误是没有办法使用 try...catch 的。

Promise提供的错误处理机制,是通过catch方法进行捕获。

try {
    Promise.reject()
} catch(err) {
    // 这里啥都 catch 不到
    console.log(err)
}

fs.copy(
    buildStatic,
    aresStatic
).then(() => {
    console.log(`${buildStatic} -> ${aresStatic}`)
}).catch(err => {
    // 这里可以捕获到报错
    console.log(err)
})

async/await + try catch

async/await语法糖加上try...catch语句进行的。这样做的好处是异步和同步调用都能够使用统一的方式进行处理了。

对于异步代码,建议统一转换成Promise然后采用async/await + try...catch这种方式进行处理。这样风格统一,程序的健壮性也大大加强。

async function one() {
    // a未定义
    a.b = 3
}
  
async function test() {
    try {
        await one();
    } catch(error) {
        //  a is not defined
        console.log(error);
    }
}
  
test();

unhandledRejection

实际开发中,总是会有一些 Promise 被遗漏掉catch处理,没有得到错误处理,会导致应用crash。我们可以通过**unhandledrejection** 事件捕获未处理的 Promise 错误。

实现原理:Node.js 会在每次 Tick 执行完后检查是否有未捕获的错误 Promise,如果有,则触发 unhandledRejection事件。

process.on('unhandledRejection', (reason, p) => {
    console.log('Unhandled Rejection at:', p, 'reason:', reason);
});

特殊情况如何捕获异常

如果是回调函数中捕获异常怎么做?用domain去捕获,domian捕获会抛出500错误,但是domain捕获有一个问题,会丢失栈信息,无法保证程序健康进行,所以要结束进程,在回调函数中process.exit(1),然后用node的server.close方法再去释放,server.close连接释放后自动结束进程,所以不用在server.close中去结束进程process.exit(1)uncaughtExpection捕获异常的的原理就是:uncaughtExpection事件存在回调函数process.on("uncaughtExpection",callback)时node不会强制结束进程,这样可弥补domain丢失stack的问题
所以domian去捕获绝大部分回调函数中的异常,uncaughtExpection去捕获丢失stack异常,这样就完整了

app.use(function(req,res,next){
      var reqDomain = domain.create();
      reqDomain.on("err",function(){
        try {
          var killTimer = setTimeout(function(){
            process.exit(1);
          },1000)
          killTimer.unref();
          server.close();
          res.send(500);
        } catch(e) {
          // statements
          console.log(e.stack);
        }
      })
      reqDomain.run(next);
  });

process.on("uncaughtException",function(err){
  console.log(err);
  try{
    var killTimer = setTimeout(function(){
      process.exit(1)
    },1000)
    killTimer.unref();
    server.close();
  }catch(e){
    console.log(e.stack);
  }
});

uncaughtException

uncaughtException 也是 NodeJS 进程的一个事件。如果进程里产生了一个异常而没有被任何Try Catch捕获会触发这个事件。

NodeJS 对于未捕获异常的默认处理是:

    - 触发 uncaughtException 事件

    - 如果 uncaughtException 没有被监听

    - 打印异常的堆栈信息

    - 触发进程的 exit 事件

所以如果某个报错没有被任意try catch捕获,且没有定义uncaughtException事件,就会导致程序退出。

process.on('unhandledRejection', (reason, p) => {
    console.log('Unhandled Rejection at: Promise', p, 'reason:', reason)
})

Express错误处理

Express中,路由或中间件报错处理可以通过特殊的中间件来完成。

一般中间件的参数为3个:req,resnext。如果你use一个4个参数的中间件,它将被Express视为错误处理中间件。

app.get('/a',function(req,res,next){
    res.end('hahah');
    next(new Error('错误啦'));
});
app.use('/a',function(err,req,res,next){
    console.log('路由错误'+err);
})
//all error中间件
app.use(function(err, req, res, next) {
    console.log("Error happens", err.stack);
});
//错误传递,/a的错误处理首先匹配/a那个错误中间件,如果不用next就不会传递到全局错误处理中间件
//如果在/a错误处理中间件里调用next(err) 那么全局错误中间件也会被执行

到此这篇关于Node端异常捕获的实现方法的文章就介绍到这了,更多相关Node 异常捕获内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 快速查询nodejs版本信息的六种方法

    快速查询nodejs版本信息的六种方法

    Node.js是一款基于Chrome V8引擎的快速、轻量级的JavaScript运行时,随着应用程序规模越来越庞大,Node.js版本的更新也日益频繁,这篇文章旨在帮助开发者们快速查询Node.js版本信息,需要的朋友可以参考下
    2023-11-11
  • NodeJS服务器实现gzip压缩的示例代码

    NodeJS服务器实现gzip压缩的示例代码

    这篇文章主要介绍了NodeJS服务器实现gzip压缩的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-10-10
  • Node.js实现mysql连接池使用事务自动回收连接的方法示例

    Node.js实现mysql连接池使用事务自动回收连接的方法示例

    这篇文章主要介绍了Node.js实现mysql连接池使用事务自动回收连接的方法,结合实例形式分析了node.js操作mysql连接池实现基于事务的连接回收操作相关技巧,需要的朋友可以参考下
    2018-02-02
  • 在Mac下彻底卸载node和npm的方法

    在Mac下彻底卸载node和npm的方法

    今天小编就为大家分享一篇在Mac下彻底卸载node和npm的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-05-05
  • Nodejs使用exceljs实现excel导入导出

    Nodejs使用exceljs实现excel导入导出

    在日常开发中,我们常需在后台管理系统中实现数据的导入与导出功能,以便与 Excel 文件进行交互,本文将使用使用exceljs实现excel导入导出功能,需要的可以参考下
    2024-03-03
  • 如何正确使用Nodejs 的 c++ module 链接到 OpenSSL

    如何正确使用Nodejs 的 c++ module 链接到 OpenSSL

    这篇文章主要介绍了如何正确使用Nodejs 的 c++ module 链接到 OpenSSL,需要的朋友可以参考下
    2014-08-08
  • Nodejs 微信小程序消息推送的实现

    Nodejs 微信小程序消息推送的实现

    这篇文章主要介绍了Nodejs 微信小程序消息推送的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • node.js实现http服务器与浏览器之间的内容缓存操作示例

    node.js实现http服务器与浏览器之间的内容缓存操作示例

    这篇文章主要介绍了node.js实现http服务器与浏览器之间的内容缓存操作,结合实例形式分析了node.js http服务器与浏览器之间的内容缓存原理与具体实现技巧,需要的朋友可以参考下
    2020-02-02
  • nodejs中简单实现Javascript Promise机制的实例

    nodejs中简单实现Javascript Promise机制的实例

    这篇文章主要介绍了nodejs中简单实现Javascript Promise机制的实例,本文在nodejs中简单实现一个promise/A 规范,需要的朋友可以参考下
    2014-12-12
  • Node.js 基础教程之全局对象

    Node.js 基础教程之全局对象

    这篇文章主要介绍了Node.js 基础教程之全局对象的相关资料,Node.js 中的全局对象是 global,所有全局变量(除了 global 本身以外)都是 global 对象的属性,需要的朋友可以参考下
    2017-08-08

最新评论