Nodejs错误处理详细指南
Nodejs错误处理详细指南
学习 Node.js
中的高级错误处理技术,以增强应用程序的可靠性和稳定性。
在 Node.js
中,我们可以使用各种技术和方法来处理错误,可以查看这篇文章。错误处理是任何 Node.js
应用程序的一个重要方面。正确管理错误可以显着提高代码库的稳定性、可靠性和可维护性。在这篇文章中,我们将探索 Node.js
中错误处理的各种最佳实践和技术,使我们能够像经验丰富的 Node.js
开发人员一样处理错误。
我们可以在 Node.js
中采用多种高级错误处理技术。这些技术允许对错误处理进行更精细的控制,增强错误报告并提高代码可维护性。以下是 Node.js
中的一些高级错误处理技术:
- 错误中间件
- 错误处理框架
- 错误冒泡
- 优雅关机
- 错误监控和报告
- 断路器模式
- 背压处理
- 自动重试
- 日志记录和分析
1. 错误中间件
Express
等框架中的错误中间件功能允许我们处理请求处理期间发生的错误。当错误传递到 next
方法时,将执行这些错误处理函数。以下是逐步细分的步骤:
步骤1:定义错误中间件函数,有四个参数:err
、req
、res
和next
。
app.use((err, req, res, next) => {// Handle the error
});
步骤2:在错误中间件函数内处理错误。我们可以访问错误消息、状态代码和其他相关详细信息,以制定适当的错误响应。
app.use((err , req, res, next ) => { //处理错误res.status (err.status || 500 ).json({ error : err.message });
});
示例1
app.get('/users/:id', (req, res, next) => {const userId = req.params.id;
if (userId === 'admin') {const error = new Error('Access denied');error.status = 403;next(error);} else {// Handle the regular flow}
});
app.use((err, req, res, next) => {res.status(err.status || 500).json({ error: err.message });
});
在此示例中,当请求 ID
为 admin
的用户时,我们创建一个自定义错误对象并将其传递给next()
。 错误中间件函数捕获错误并发送正确的 JSON
响应,状态代码为 403
(禁止)。
示例2
app.get('/data', async (req, res, next) => {try {const data = await fetchData();res.json(data);} catch (error) {next(error);}
});app.use((err, req, res, next) => {res.status(err.status || 500).json({ error: err.message });
});
在此示例中,异步路由处理程序获取数据。如果异步操作期间发生错误,则使用 try-catch
块捕获错误,并将错误传递给next()
。 错误中间件函数处理错误并发送适当的响应。
2. 错误处理框架
Node.js
生态系统中有多个错误处理框架和库提供了高级错误处理功能。我们现在只介绍两个比较流行的例子:Boom
和 Youch
。
示例1:使用Boom
const express = require('express');
const boom = require('@hapi/boom');const app = express();
app.get('/users/:id', (req, res, next) => {const userId = req.params.id;if (userId === 'admin') {next(boom.forbidden('Access denied'));} else {// ...}
});
app.use((err, req, res, next) => {if (!err.isBoom) {next(err);return;}const { output } = err;res.status(output.statusCode).json({ error: output.payload });
});
在此示例中,使用boom.forbidden()
方法创建拒绝访问错误。当用户ID是admin
时,错误被传递到错误中间件函数。错误中间件检查错误是否为 Boom
错误并发送格式化的 JSON
响应。
示例2:使用Youch
const express = require('express');
const youch = require('youch');const app = express();
app.get('/users/:id', (req, res, next) => {const userId = req.params.id;if (userId === 'admin') {const error = new Error('Access denied');next(error);} else {// ...}
});
app.use((err, req, res, next) => {const youchInstance = new youch(err, req);youchInstance.toJSON().then((errorJSON) => {res.status(500).json(errorJSON);});
});
3. 错误冒泡
正确的错误冒泡可确保在应用程序中适当的地方捕获和处理错误。可以通过将错误抛出到同步代码中或在异步代码中返回被拒绝的 Promise
来冒泡。让我们进一步探讨这个话题:
抛出错误(同步)
在同步代码中,我们可以使用throw
语句抛出一个错误。错误将在调用堆栈中向上冒泡,直到被 try-catch
块捕获。
function divide(a, b) {if (b === 0) {throw new Error('Cannot divide by zero');}return a / b;
}try {const result = divide(10, 0);console.log(result);
} catch (error) {console.error('An error occurred:', error);
}
在此示例中,divide
函数在尝试除以零时抛出错误。该错误在try-catch
代码块中捕获并进行相应的处理。
Promise.reject(异步)
在使用 Promise
的异步代码中,可以通过使用Promise.reject()
方法返回被拒绝的 Promise
来抛出错误。
function fetchData() {return new Promise((resolve, reject) => {// Simulating an asynchronous operationsetTimeout(() => {reject(new Error('Data fetch failed'));}, 2000);});
}fetchData().then((data) => {console.log(data);}).catch((error) => {console.error('An error occurred:', error);});
在此示例中,fetchData
函数返回一个 Promise
,Promise
在延迟后被故意拒绝。使用Promise
链上的catch
方法捕获错误并进行相应处理。
4. 优雅关机
在应用程序中实现优雅的关闭机制允许我们在关闭过程中处理错误。这涉及在终止应用程序之前正确关闭数据库连接、释放资源以及通知外部服务。让我们看看一些示例:
示例1:处理终止信号
侦听 SIGINT
(Ctrl+C
) 和 SIGTERM
等终止信号,并在退出应用程序之前执行清理任务。
process.on('SIGINT', () => {// 退出控制台前清理任务console.log('优雅关闭...');// 关闭数据库连接等操作process.exit(0); // 退出
});
示例2:注册清理处理程序
注册清理处理程序以确保即使在意外错误情况下也能正确清理。
process.on('uncaughtException', (error) => {console.error('Uncaught Exception:', error);process.exit(1); // Exit with error code
});process.on('unhandledRejection', (reason, promise) => {console.error('Unhandled Promise Rejection:', reason);process.exit(1); // Exit with error code
});
在此示例中,我们处理未捕获的异常和未处理的承诺拒绝,并在退出应用程序之前执行清理任务。
5. 错误监控和报告
将错误监控和报告工具集成到我们的应用程序中有助于跟踪、分析和报告生产环境中发生的错误。让我们看看所涉及的步骤:
第 1 步:选择错误监控服务
选择错误监控服务/工具,例如 Sentry
、Bugsnag
或 Rollbar
。
步骤2:安装并配置错误监控服务
为所选服务安装错误监控库,并使用我们的 API
密钥或特定于项目的设置对其进行配置。
第 3 步:将错误监控集成到应用程序中
const express = require('express');
const app = express();// Error monitoring library initialization
const Sentry = require('@sentry/node');
Sentry.init({ dsn: 'YOUR_DSN_HERE' });
app.get('/', (req, res) => {// Some code that may throw an errorthrow new Error('Error occurred!');
});
// Error handler middleware
app.use((err, req, res, next) => {Sentry.captureException(err); // Report the error to Sentryres.status(500).json({ error: 'Something went wrong' });
});
app.listen(3000, () => {console.log('Server started on port 3000');
});
在本例中,我们使用Sentry
错误监控服务。我们使用提供的 DSN
(数据源名称)对其进行初始化,并在错误处理中间件中使用Sentry.captureException()
捕获异常。
6. 断路器模式
断路器模式有助于管理故障并防止分布式系统中的级联故障。通过将远程服务调用包装在断路器中,我们可以处理错误、提供回退响应并避免系统不堪重负。让我们看看所涉及的步骤:
第 1 步:选择断路器库
选择类似opossum
或 brakes
的断路器库来实现断路器模式。
第 2 步:包装远程服务调用
将远程服务调用包装在断路器中以处理错误并提供回退响应。
const CircuitBreaker = require('opossum');const options = {errorThresholdPercentage: 50,timeout: 3000,resetTimeout: 30000,
};
const breaker = new CircuitBreaker(remoteServiceCall, options);
breaker.fallback(() => {return 'Fallback response';
});
app.get('/', (req, res) => {breaker.fire().then((result) => {res.json(result);}).catch((error) => {res.status(500).json({ error: 'Service unavailable' });});
});
在此示例中,我们使用opossum
库来实现断路器模式。我们在进行远程服务调用时定义回退响应并处理错误。
7. 背压处理
在处理大容量流或异步操作时,背压处理至关重要。实施背压机制可以防止过载并实现更好的错误处理。以下是涉及的步骤:
第 1 步:使用背压感知流
利用背压感知流,例如Node.js
中的ReadStream
、WriteStream
这些API
来实现自动处理流量控制。
第 2 步:暂停和恢复流
暂停和恢复流以控制数据流。当可写流尚未准备好处理数据时,暂停可读流。
const fs = require('fs');const readableStream = fs.createReadStream('largeFile.txt');
const writableStream = fs.createWriteStream('output.txt');
writableStream.on('drain', () => {readableStream.resume();
});
readableStream.on('data', (chunk) => {if (!writableStream.write(chunk)) {readableStream.pause();}
});
在此示例中,可读流从大文件中读取数据,可写流将数据写入输出文件。
8. 自动重试
自动重试是一种使用指数退避策略自动重试失败操作(例如网络请求)的技术。它有助于处理暂时性错误并自动恢复。让我们看看所涉及的步骤:
第 1 步:选择重试库
选择类似async-retry
的重试库或实现我们自己的重试逻辑。
第 2 步:定义重试选项
定义重试选项,包括重试尝试次数、退避策略和重试条件。
const retry = require('async-retry');const retryOptions = {retries: 3,minTimeout: 1000,maxTimeout: 5000,onRetry: (error) => {console.error('Retrying due to error:', error);},
};
步骤 3:重试操作
将可能失败的操作包装在重试函数中,并传入重试选项。
retry(async () => {// Operation that may failawait fetchSomeData();
}, retryOptions).then((result) => {console.log('Operation succeeded:', result);}).catch((error) => {console.error('Operation failed after retries:', error);});
在此示例中,async-retry
库将fetchSomeData()
方法指定的重试选项并进行自动重试操作。
9. 日志记录和分析
记录错误和收集分析对于故障排除和调试至关重要。正确的日志记录策略可以提供错误可见性并帮助跟踪应用程序性能。让我们看看所涉及的步骤:
第 1 步:选择日志库或服务
选择像 Winston
这样的日志库或像 ELK Stack
(Elasticsearch
、Logstash
、Kibana
)或 Splunk
这样的日志服务。
第2步:配置日志系统
使用适当的传输配置日志记录系统,例如控制台日志记录或文件日志记录,并设置日志级别。
const winston = require('winston');const logger = winston.createLogger({level: 'info',format: winston.format.simple(),transports: [new winston.transports.Console(),new winston.transports.File({ filename: 'application.log' }),],
});
步骤 3:记录错误和相关信息
在应用程序代码中记录错误、堆栈跟踪和其他相关信息。
try {// Code that may throw an error
} catch (error) {logger.error('An error occurred:', error);
}
示例1: 将错误记录到控制台
const winston = require('winston');const logger = winston.createLogger({level: 'error',format: winston.format.simple(),transports: [new winston.transports.Console()],
});
try {// Code that may throw an errorthrow new Error('Something went wrong');
} catch (error) {logger.error('An error occurred:', error);
}
在此示例中,我们使用 Winston
日志记录库将错误以错误日志级别记录到控制台。
示例2: 将错误记录到文件
const winston = require('winston');const logger = winston.createLogger({level: 'error',format: winston.format.simple(),transports: [new winston.transports.File({ filename: 'application.log' })],
});
try {// Code that may throw an errorthrow new Error('Something went wrong');
} catch (error) {logger.error('An error occurred:', error);
}
在此示例中,我们配置 Winston
记录器将错误记录到名为application.log
的文件中.
结论
Node.js
中的错误处理是构建健壮且可靠的应用程序的一个关键方面。通过遵循最佳实践(例如使用 try-catch
块、创建自定义错误类、处理异步错误以及实施错误日志记录和报告),我们可以有效地管理代码库中的错误并从中进行维护。
相关文章:
Nodejs错误处理详细指南
Nodejs错误处理详细指南 学习 Node.js 中的高级错误处理技术,以增强应用程序的可靠性和稳定性。 在 Node.js 中,我们可以使用各种技术和方法来处理错误,可以查看这篇文章。错误处理是任何 Node.js 应用程序的一个重要方面。正确管理错误可以…...
软考 系统架构设计师系列知识点之软件架构风格
这个十一注定是一个不能放松、保持“紧”的十一。由于报名了全国计算机技术与软件专业技术资格(水平)考试,11月4号就要考试,因此8天长假绝不能荒废,必须要好好利用起来。现在将各个核心知识点一一进行提炼并做记录。 所…...

一键智能视频语音转文本——基于PaddlePaddle语音识别与Python轻松提取视频语音并生成文案
前言 如今进行入自媒体行业的人越来越多,短视频也逐渐成为了主流,但好多时候是想如何把视频里面的语音转成文字,比如,录制会议视频后,做会议纪要;比如,网课教程视频,想要做笔记&…...
[unity]对象的序列化
序 抽象的图纸叫类,包含具体数据的叫对象。 类的序列化和反序列化 using System.Collections; using System.Collections.Generic; using UnityEngine;using System; using System.IO; using System.Runtime.Serialization.Formatters.Binary; [Serializabl…...
java开发岗位面试
java开发岗位面试 技术栈:springboot框架+redis 个人笔试/技术面问题整理 1、SpringBoot有什么组件? 举例说几个: ①auto-configuration组件:核心特征。其约定大于配置思想,赋予了SpringBoot开箱即用的强…...

坠落防护 挂点装置
声明 本文是学习GB 30862-2014 坠落防护 挂点装置. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本标准规定了高处坠落防护挂点装置的技术要求、检验方法、检验规则及标识。 本标准适用于防护高处坠落的挂点装置。 本标准不适用于体育及消…...

关于 自定义的RabbitMQ的RabbitMessageContainer注解-实现原理
概述 RabbitMessageContainer注解 的主要作用就是 替换掉Configuration配置类中的各种Bean配置; 采用注解的方式可以让我们 固化配置,降低代码编写复杂度、减少配置错误情况的发生,提升编码调试的效率、提高业务的可用性。 为什么说“降低…...

uniapp快速入门系列(1)- 概述与基础知识
章节三:抖音小程序页面开发 第1章:概述与基础知识1.1 uniapp简介1.1.1 什么是uniapp?1.1.2 为什么选择uniapp?1.1.3 uniapp与微信小程序的关系 1.2 HBuilderX介绍与安装1.2.1 什么是HBuilderX?1.2.2 HBuilderX的安装1.…...

国密国际SSL双证书解决方案,满足企事业单位国产国密SSL证书要求
近年来,为了摆脱对国外技术和产品的依赖,建设安全的网络环境,以及加强我国对网络信息的安全可控能力,我国推出了国密算法。同时,为保护网络通信信息安全,更高级别的安全加密数字证书—国密SSL证书应运而生。…...

LabVIEW开发虚拟与现实融合的数字电子技术渐进式实验系统
LabVIEW开发虚拟与现实融合的数字电子技术渐进式实验系统 数字电子技术是所有电气专业的重要学科基础,具有很强的理论性和实践性。其实验是提高学生分析、设计和调试数字电路能力,培养学生解决实际问题的工程实践能力,激发学生创新意识&…...

机器学习之单层神经网络的训练:增量规则(Delta Rule)
文章目录 权重的调整单层神经网络使用delta规则的训练过程 神经网络以权值的形式存储信息,根据给定的信息来修改权值的系统方法称为学习规则。由于训练是神经网络系统地存储信息的唯一途径,因此学习规则是神经网络研究中的一个重要组成部分 权重的调整 (…...

C# Task任务详解
文章目录 前言Task返回值无参返回有参返回 async和await返回值await搭配使用Main async改造 Task进阶Task线程取消测试用例超时设置 线程暂停和继续测试用例 多任务等最快多任务全等待 结论 前言 Task是对于Thread的封装,是极其优化的设计,更加方便了我…...

百度网盘的扩容
百度网盘的扩容怎么扩 百度网盘的扩容通常需要购买额外的存储空间。以下是扩容百度网盘存储空间的一般步骤: 登录百度网盘:首先,在您的计算机或移动设备上打开百度网盘,并使用您的百度账号登录。 选择扩容选项:一旦登…...
Android 悬浮窗
本文参考文章地址:https://juejin.cn/post/7009180088310693919 一、申请权限 <uses-permission android:name"android.permission.SYSTEM_ALERT_WINDOW" />二、创建悬浮窗service <serviceandroid:name".FloatingWindowService"an…...

3.物联网射频识别,(高频)RFID应用ISO14443-2协议
一。ISO14443-2协议简介 1.ISO14443协议组成及部分缩略语 (1)14443协议组成(下面的协议简介会详细介绍) 14443-1 物理特性 14443-2 射频功率和信号接口 14443-3 初始化和防冲突 (分为Type A、Type B两种接口&…...
数据分析笔记1
数据分析概述:数据获取--探索分析与可视化--预处理--分析建模--模型评估 数据分析含义:利用统计与概率的分析方法提取有用的信息,最后进行总结与概括 一、数据获取 实用网站:kaggle 阿里云天池 数据仓库:将所有业务数据…...
paramiko 3
import paramiko import concurrent.futuresdef execute_remote_command(hostname, username, password, command):try:# 创建SSH客户端client paramiko.SSHClient()client.set_missing_host_key_policy(paramiko.AutoAddPolicy())# 使用密码认证连接远程主机client.connect(h…...
基于Dlib训练自已的人脸数据集提高人脸识别的准确率
前言 由于图像的质量、光线、角度等因素影响。这时如果使用官方提供的模型做人脸识别,就会导至识别率不是很理想。人脸识别的准确率与图像的清晰度和质量有关。如果图像模糊、光线不足或者有其他干扰因素,Dlib 可能无法正确地识别人脸。为了确保图像质量…...
Git 详细安装教程(详解 Git 安装过程的每一个步骤
Git 详细安装教程(详解 Git 安装过程的每一个步骤) 该文章详细具体,值得收藏学习...
kafka伪集群部署,使用KRAFT模式
1:拉去管理kafka界面UI镜像 docker pull provectuslabs/kafka-ui2:拉去管理kafka镜像 docker pull bitnami/kafka3:docker-compose.yml version: 3.8 services:kafka-1:container_name: kafka1image: bitnami/kafka ports:- "19092:19092"- "19093:19093&quo…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
探索Selenium:自动化测试的神奇钥匙
目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台
淘宝扭蛋机小程序系统的开发,旨在打造一个互动性强的购物平台,让用户在购物的同时,能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机,实现旋转、抽拉等动作,增…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...
Oracle11g安装包
Oracle 11g安装包 适用于windows系统,64位 下载路径 oracle 11g 安装包...

李沐--动手学深度学习--GRU
1.GRU从零开始实现 #9.1.2GRU从零开始实现 import torch from torch import nn from d2l import torch as d2l#首先读取 8.5节中使用的时间机器数据集 batch_size,num_steps 32,35 train_iter,vocab d2l.load_data_time_machine(batch_size,num_steps) #初始化模型参数 def …...
LeetCode 0386.字典序排数:细心总结条件
【LetMeFly】386.字典序排数:细心总结条件 力扣题目链接:https://leetcode.cn/problems/lexicographical-numbers/ 给你一个整数 n ,按字典序返回范围 [1, n] 内所有整数。 你必须设计一个时间复杂度为 O(n) 且使用 O(1) 额外空间的算法。…...

第2课 SiC MOSFET与 Si IGBT 静态特性对比
2.1 输出特性对比 2.2 转移特性对比 2.1 输出特性对比 器件的输出特性描述了当温度和栅源电压(栅射电压)为某一具体数值时,漏极电流(集电极电流...

python3GUI--基于PyQt5+DeepSort+YOLOv8智能人员入侵检测系统(详细图文介绍)
文章目录 一.前言二.技术介绍1.PyQt52.DeepSort3.卡尔曼滤波4.YOLOv85.SQLite36.多线程7.入侵人员检测8.ROI区域 三.核心功能1.登录注册1.登录2.注册 2.主界面1.主界面简介2.数据输入3.参数配置4.告警配置5.操作控制台6.核心内容显示区域7.检…...