当前位置: 首页 > news >正文

【Node.js从基础到高级运用】十九、Node.js 捕获错误之“未捕获的异常”

引言

在 Node.js 应用程序中,错误处理是保证应用稳定性和可靠性的关键部分。特别是“未捕获的异常”(uncaught exceptions),如果不妥善处理,很可能会导致整个进程崩溃。在本文中,我们将探讨如何在 Node.js 中捕获和处理未捕获的异常,并使用 Jest 框架进行测试。

什么是“未捕获的异常”?

在 Node.js 中,当一个异常没有被 try/catch 语句捕获时,它就会成为一个“未捕获的异常”。默认情况下,Node.js 会打印出错误信息,并退出当前进程。

如何捕获“未捕获的异常”?

为了防止进程因为未捕获的异常而退出,我们可以监听 process 对象的 uncaughtException 事件。

process.on('uncaughtException', (error) => {// 打印错误信息console.error('捕获到未处理的异常:', error);// 执行必要的清理操作// ...// 在完成清理后,可以选择退出进程process.exit(1);
});

示例代码

下面是一个简单的 Node.js 应用程序,它演示了如何捕获未捕获的异常:

// 引入 fs 模块用于文件操作
const fs = require('fs');// 监听未捕获的异常
process.on('uncaughtException', (error) => {console.error('捕获到未处理的异常:', error);// 清理工作可以在这里进行process.exit(1); // 退出进程
});// 一个会产生未捕获异常的函数
function readFileAsync() {// 异步读取一个不存在的文件,将会产生异常fs.readFile('/path/to/nonexistent/file', (err, data) => {if (err) {// 这里故意不处理错误,导致未捕获的异常throw err;}console.log(data);});
}// 调用函数,产生未捕获的异常
readFileAsync();

在上面的代码中,readFileAsync 函数尝试读取一个不存在的文件,这会导致一个错误。由于错误没有在回调函数中被处理,它会被抛出为一个未捕获的异常。我们通过监听 uncaughtException 事件来捕获这个异常,并打印错误信息,然后退出进程。

使用 Jest 进行测试

为了测试我们的错误处理逻辑,我们可以使用 Jest 测试框架。首先,我们需要安装 Jest:

npm install --save-dev jest

然后,我们可以编写一个测试用例来模拟未捕获的异常,并断言我们的错误处理逻辑是否按预期工作。

创建一个 test19.test.js 文件,包含以下内容:

// 文件:test19.test.jsfunction setupUncaughtExceptionListener() {process.on('uncaughtException', (error) => {console.error('Unhandled exception:', error);});
}describe('setupUncaughtExceptionListener', () => {it('应使用“uncaughtException”调用process.on', () => {// 监视 process.on 方法const processSpy = jest.spyOn(process, 'on');// 调用目标函数setupUncaughtExceptionListener();// 验证 process.on 是否被调用,并且参数正确expect(processSpy).toHaveBeenCalledWith('uncaughtException', expect.any(Function));// 清理监视器processSpy.mockRestore();});it('发生uncaughtException时应调用console.error', () => {// 监视 console.error 方法const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {});// 初始化未捕获异常监听器setupUncaughtExceptionListener();// 模拟一个未捕获的异常const testError = new Error('Test uncaught exception');process.emit('uncaughtException', testError);// 验证 console.error 是否被调用,并且传入了正确的错误信息expect(consoleSpy).toHaveBeenCalledWith('Unhandled exception:', testError);// 清理监视器consoleSpy.mockRestore();});
});

最后,我们可以运行 Jest 来执行测试:

npx jest test19.test.js

如果一切正常,你应该会看到所有测试通过的消息,包括新添加的测试用例,它验证了当 uncaughtException 事件发生时console.error是否被正确调用,并且输出了预期的错误信息。
这个测试案例展示了如何在 Node.js 环境中模拟未捕获的异常事件,并验证相关的错误处理函数是否按预期工作。通过使用 jest.spyOn .mockImplementation,我们能够监视和断言 console.error 的调用,同时避免了在测试中输出不必要的错误信息。

在 Jest 中,还原模拟的函数通常使用mockRestore()方法(对于通过jest.spyOn创建的模拟)或者直接将函数赋值回原来的实现(对于直接赋值模拟的情况)。这样,每个测试用例都可以在一个干净的环境中运行,不受之前测试用例的影响

总结

正确处理未捕获的异常对于维护 Node.js 应用的稳定性至关重要。通过监听 uncaughtException 事件,并在必要时进行适当的清理和退出,我们可以避免一些突发的错误导致整个应用崩溃。同时,使用 Jest 进行测试可以帮助我们确保我们的错误处理代码按预期工作。

相关文章:

【Node.js从基础到高级运用】十九、Node.js 捕获错误之“未捕获的异常”

引言 在 Node.js 应用程序中,错误处理是保证应用稳定性和可靠性的关键部分。特别是“未捕获的异常”(uncaught exceptions),如果不妥善处理,很可能会导致整个进程崩溃。在本文中,我们将探讨如何在 Node.js …...

vue 计算属性

基础示例​ 模板中的表达式虽然方便,但也只能用来做简单的操作。如果在模板中写太多逻辑,会让模板变得臃肿,难以维护。比如说,我们有这样一个包含嵌套数组的对象: const author reactive({name: John Doe,books: [V…...

RedissonLock-tryLock-续期

redisson版本3.16.6 1.什么是看门狗 Redisson提供的分布式锁是支持锁自动续期的,也就是说,如果线程仍旧没有执行完,那么redisson会自动给redis中的目标key延长超时时间,这在Redisson中称之为 Watch Dog 机制。默认情况下&#x…...

MSTP环路避免实验(华为)

思科设备参考:MSTP环路避免实验(思科) 一,技术简介 MSTP(多生成树协议),MSTP解决了STP和RSTP没有考虑vlan的问题,STP和RSTP将所有的vlan共享为一个生成树实例,无法实现…...

IoT网关在智能制造工厂生产线监控与管理中的应用-天拓四方

随着工业4.0时代的到来,智能制造已成为工业发展的重要方向。IoT网关在智能制造工厂中扮演着关键角色,它能够实现设备间的互联互通、数据的实时采集与处理,以及生产线的智能监控与管理。本案例将详细介绍IoT网关在智能制造工厂生产线监控与管理…...

niushop单商户V5多店版源码分享三端uniapp打包方法包括PC端_小程序或h5端打包_收银端打包_APP端打包_商户端

目前多店版有四端uniapp,包括PC端uniapp,商家端uniapp,收银端uniapp,门店手机端uniapp,下面我总结下这些端的打包流程希望能帮助到大家,需要交流的可以看我昵称或者点我头像关注我分享代码和教程 一.niush…...

npm包发布

一、npm npm(Node Package Manager)是 Node.js 的包管理工具,用于安装、分享和管理 JavaScript 包和项目依赖。npm 是 Node.js 的默认包管理器,随同 Node.js 一起安装。 二、npm主要功能特点 包管理:npm 允许开发者…...

C#使用SQLite(含加密)保姆级教程

C#使用SQLite 文章目录 C#使用SQLite涉及框架及库复制runtimes创建加密SQLite文件生成连接字串执行SQL生成表SQLiteConnectionFactory.cs 代码结构最后 涉及框架及库 自己在NuGet管理器里面安装即可 Chloe.SQLite:ORM框架Microsoft.Data.Sqlite.Core:驱…...

C# 异步与 Unity 协程(实例讲解)

C#异步编程实例&#xff1a; 假设我们有一个需要从Web获取数据的简单应用。我们可以使用C#的异步编程模型来避免UI线程被HTTP请求阻塞 1using System.Net.Http; 2using System.Threading.Tasks; 3 4public class AsyncExample 5{ 6 public async Task<string> Fetch…...

iOS - Runloop介绍

文章目录 iOS - Runloop介绍1. 简介1.1 顾名思义1.2. 应用范畴1.3. 如果没有runloop1.4. 如果有了runloop 2. Runloop对象3. Runloop与线程4. 获取Runloop对象4.1 Foundation4.2 Core Foundation4.3 示例 5. Runloop相关的类5.1 Core Foundation中关于RunLoop的5个类5.2 CFRunL…...

探究分布式事务:深入ACID特性在分布式系统中的挑战与解决方案

✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天开心哦&#xff01;✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; ✨✨ 帅哥美女们&#xff0c;我们共同加油&#xff01;一起进步&am…...

PCI总线管脚定义(引脚定义)

文章目录 1&#xff1a; 参考资料的链接2: 图片说明3&#xff1a;PCI文字说明每日好图 1&#xff1a; 参考资料的链接 PCI bus pinout PCI三种标准引脚信号定义 PCI bus pinout 2: 图片说明 A面和B面正反 PCI Universal Card 32/64 bit ----------------------------------…...

万字详解PHP+Sphinx中文亿级数据全文检索实战(实测亿级数据0.1秒搜索耗时)

Sphinx查询性能非常厉害&#xff0c;亿级数据下输入关键字&#xff0c;大部分能在0.01~0.1秒&#xff0c;少部分再5秒之内查出数据。 Sphinx 官方文档&#xff1a;http://sphinxsearch.com/docs/sphinx3.html极简概括&#xff1a; 由C编写的高性能全文搜索引擎的开源组件&…...

数据库索引及优化

数据库索引及优化 什么是索引&#xff1f; MySQL官方对索引的定义为&#xff1a;索引&#xff08;INDEX&#xff09;是帮助MySQL高效获取数据的数据结构。 索引的本质&#xff1a; 数据结构 为什么要引入索引&#xff1f; 引入索引的目的在于提高查询效率&#xff0c;就好像是…...

flink: 将接收到的tcp文本流写入HBase

一、依赖&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.o…...

SpringBoot集成knife4j

SpringBoot集成knife4j 1、什么是Knife4j2、SpringBoor整合Knife4j2.1、Knife4j配置方式12.2 配置方式二2.3、写注解2.4、效果 1、什么是Knife4j 在日常开发中&#xff0c;写接口文档是我们必不可少的&#xff0c;而Knife4j就是一个接口文档工具&#xff0c;可以看作是Swagger…...

Vue3之setup方法

Vue 3 的 setup 方法是 Vue Composition API 的一部分&#xff0c;用于组织和复用 Vue 组件的逻辑代码。Vue Composition API 允许您以更具响应性和函数式的方式来组织和复用 Vue 组件中的代码&#xff0c;特别是在处理复杂逻辑或跨组件共享逻辑时非常有用。 以下是关于 setup…...

MySQL常见索引及其创建

MySQL索引 在 MySQL 数据库中&#xff0c;常见的索引类型包括以下几种&#xff1a; 普通索引&#xff08;Normal Index&#xff09;&#xff1a;最基本的索引类型&#xff0c;没有任何限制。唯一索引&#xff08;Unique Index&#xff09;&#xff1a;要求索引列的值是唯一的…...

高效测量“芯”搭档 | ACM32激光测距仪应用方案

激光测距仪概述 激光测距仪是利用激光对目标的距离进行准确测定的仪器。激光测距仪在工作时向目标射出一束很细的激光&#xff0c;由光电元件接收目标反射的激光束&#xff0c;计时器测定激光束从发射到接收的时间&#xff0c;计算出从观测者到目标的距离。激光测距仪分为手持激…...

基于Hive大数据分析springboot为后端以及vue为前端的的民宿系

标题基于Hive大数据分析springboot为后端以及vue为前端的的民宿系 本文介绍了如何利用Hive进行大数据分析,并结合Spring Boot和Vue构建了一个民宿管理系统。该民民宿管理系统包含用户和管理员登陆注册的功能,发布下架酒店信息,模糊搜索,酒店详情信息展示,收藏以及对收藏的…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

NFT模式:数字资产确权与链游经济系统构建

NFT模式&#xff1a;数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新&#xff1a;构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议&#xff1a;基于LayerZero协议实现以太坊、Solana等公链资产互通&#xff0c;通过零知…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...