【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.js

function 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 readFileAsync.test.js

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

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

总结

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/498665.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

设计模式 —— 设计原则

在软件开发中,为了提高软件系统的可维护性和可复用性,增加软件的可扩展性和灵活性,程序员要尽量根据6条原则来开发程序,从而提高软件开发效率、节约软件开发成本和维护成本。 开闭原则 对扩展开放,对修改关闭。在程序需…

【Pt】马灯贴图绘制过程 03-制作油渍、积尘效果

目录 效果 一、制作油渍效果 1.1 基本油渍 1.2 流淌的油渍痕迹 二、制作浮尘效果 三、制作积尘效果 效果 一、制作油渍效果 1.1 基本油渍 将上篇制作的“锈迹_深色”和“锈迹_浅色”两个文件夹再次合并为一个文件夹 这里就命名为“锈迹” 添加一个填充图层 设置Base …

【SpringBoot从入门到精通】01_SpringBoot概述

一、Spring与SpringBoot 1.1 Spring Spring 是一款目前主流的 Java EE 轻量级开源框架,是 Java 世界最为成功的框架之一。Spring 由“Spring 之父”Rod Johnson(罗宾约翰逊) 提出并创立,其目的是用于简化 Java 企业级应用的开发难度和开发周期。 广义…

Windows下安装使用Squirrel

引言 SQuirrel SQL Client是一个用Java写的数据库客户端,用JDBC统一数据库访问接口以后,可以通过一个统一的用户界面来操作MySQL PostgreSQL MSSQL Oracle等等任何支持JDBC访问的数据库。使用起来非常方便。而且,SQuirrel SQL Client还是一个典型的Swing程序。 如果您的工作…

基于单片机锂电池电量检测数码管显示系统设计

**单片机设计介绍,基于单片机锂电池电量检测数码管显示系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机锂电池电量检测数码管显示系统设计的主要目标是实时、准确地检测锂电池的电量,并…

LDL^H分解求逆矩阵与MATLAB仿真(Right-Looking)

通过分解将对称正定厄米特矩阵分解成下三角矩阵L和对角矩阵D来求其逆矩阵 目录 前言 一、LDL^H基本算法 二、LDL^H Right-Looking算法 三、D矩阵求逆 四、L矩阵求逆 五、A矩阵求逆 六、计算量分析 七、MATLAB仿真 八、参考资料 总结 前言 在线性代数中,LDL…

2-HDFS常用命令及上传下载流程

HDFS NameNode 安全模式(safemode) 当NameNode被重启的时候,自动进入安全模式 在安全模式中,NameNode首先会触发edits_inprogress文件的滚动。滚动完成之后,更新fsimage文件 更新完成之后,NameNode会将fsimage文件中的元数据加…

(免费分享)基于springboot,vue付费自习室系统带论文

在当今数字化时代,高效、便捷的管理系统成为了各行各业不可或缺的工具。特别是在教育服务领域,自习室作为学生和在职人员重要的学习场所,其预约和管理需求日益增长。为了满足这一市场需求,本文开发了这款基于微信小程序的付费自习…

DC-5靶机

一.环境搭建 1.下载地址 靶机下载地址:https://download.vulnhub.com/dc/DC-5.zip 2.虚拟机配置 切换nat模式,有问题全选重试和是,打到这了,我感觉这个配置我都不用写了,启动靶机如下图所示即可 二.开始渗透 1.信…

设计模式 - 简单工厂模式

文章目录 前言 大家好,今天给大家介绍一下23种常见设计模式中的一种 - 工厂模式 1 . 问题引入 请用C、Java、C#或 VB.NET任意一种面向对象语言实现一个计算器控制台程序,要求输入两个数和运算符 号,得到结果。 下面的代码实现默认认为两个操作数为Inte…

2. Java基本语法

文章目录 2. Java基本语法2.1 关键字保留字2.1.1 关键字2.1.2 保留字2.1.3 标识符2.1.4 Java中的名称命名规范 2.2 变量2.2.1 分类2.2.2 整型变量2.2.3 浮点型2.2.4 字符型 char2.2.5 Unicode编码2.2.6 UTF-82.2.7 boolean类型 2.3 基本数据类型转换2.3.1 自动类型转换2.2.2 强…

报错:torch.distributed.elastic.multiprocessing.errors.ChildFailedError:

错误: torch.distributed.elastic.multiprocessing.errors.ChildFailedError: 这个主要是torch的gpu版本和cuda不适配 我的nvcc -V是11.8 torch使用的: pip install torch2.0.1 torchvision0.15.2 torchaudio2.0.2 --index-url https://download.pyt…

Day47:WEB攻防-PHP应用文件上传函数缺陷条件竞争二次渲染黑白名单JS绕过

目录 文件上传与测试环境安装 1、前端 JS 2、.htaccess(apache独有的配置文件) 3、MIME类型 4、文件头判断 5、黑名单-过滤不严 6、黑名单-过滤不严 7、低版本GET-%00截断 8、低版本POST-%00截断 9、黑名单-过滤不严 10、逻辑不严-条件竞争 11、二次渲染 12、函数…

Leetcoder Day43| 单调栈2

503.下一个更大元素II 给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该…

2024最新Guitar Pro 8.1中文版永久许可证激活

Guitar Pro是一款非常受欢迎的音乐制作软件,它可以帮助用户创建和编辑各种音乐曲谱。从其诞生以来就送专门为了编写吉他谱而研发迭代的。 尽管这款产品可能已经成为全球最受欢迎的吉他打谱软件,在编写吉他六线谱和乐队总谱中始终处于行业领先地位&#x…

大话设计模式之原型模式

原型模式(Prototype Pattern)是一种创建型设计模式,它用于创建对象的复制,同时又能保持对象的封装。原型模式通过复制现有对象的方式来创建新的对象,而无需知道具体创建过程的细节。 在原型模式中,通常会有…

Excel·VBA数组分组问题

看到一个帖子《excel吧-数据分组问题》,对一组数据分成4组,使每组的和值相近 目录 代码思路1,分组形式、可分组数代码1代码2代码2举例 2,数组所有分组形式举例 这个问题可以转化为2步:第1步,获取一组数据…

【大数据运维】minio 常见shell操作

文章目录 1. 安装2. 入门操作3. 命令帮助 1. 安装 下载 https://dl.min.io/client/mc/release/linux-amd64/ 赋权与使用 cp mc /usr/bin && chmod x /usr/bin/mc ./mc --help 2. 入门操作 # 添加minio到mc mc config host add minio_alias_name endpoint_adress …

SpringBoot动态数据源实现

一、背景 一个应用难免需要连接多个数据库,像我们系统起码连接了5个以上数据库,AWS RDS主库,ECS自搭MySQL从库,工厂系统三个SQLServer数据库,在线网站MySQL数据库,记得很早以前是用SessionFactory配置&…

Java中有哪些容器(集合类)?

Java中的集合类主要由Collection和Map这两个接口派生而出,其中Collection接口又派生出三个子接 口,分别是Set、List、Queue。所有的Java集合类,都是Set、List、Queue、Map这四个接口的实现 类,这四个接口将集合分成了四大类&#…
最新文章