Node.js API详解之 Error模块用法实例分析


Posted in Javascript onMay 14, 2020

本文实例讲述了Node.js API详解之 Error模块用法。分享给大家供大家参考,具体如下:

Node.js API详解之 Error

Node.js 中运行的应用程序一般会遇到以下四类错误:
1.标准的 JavaScript 错误:
EvalError : 当调用 eval() 失败时抛出。
SyntaxError : 当 JavaScript 语法错误时抛出。
RangeError : 当值不在预期范围内时抛出。
ReferenceError : 当使用未定义的变量时抛出。
TypeError : 当传入错误类型的参数时抛出。
URIError : 当全局的 URI 处理函数被误用时抛出。
2.由底层操作系触发的系统错误,例如试图打开一个不存在的文件、试图通过一个已关闭的 socket 发送数据等。
3.由应用程序代码触发的用户自定义的错误。
4.断言错误是错误的一个特殊类别,每当 Node.js 检测到一个不应该发生的异常逻辑时触发。 这类错误通常由 assert 模块引起。
所有由 Node.js 引起的 JavaScript 错误与系统错误都继承自或实例化自标准的 JavaScript 类,且保证至少提供类中的属性。

错误的冒泡和捕获

说明:

Node.js 支持几种当应用程序运行时发生的错误的冒泡和处理的机制。
如何报告和处理这些错误完全取决于错误的类型和被调用的 API 的风格。
所有 JavaScript 错误都会被作为异常处理,异常会立即产生并使用标准的 JavaScript throw 机制抛出一个错误。
这些都是使用 JavaScript 语言提供的 try / catch 语句处理的。
JavaScript 的 throw 机制的任何使用都会引起异常,异常必须使用 try / catch 处理,
否则 Node.js 进程会立即退出。

除了少数例外,同步的 API(任何不接受 callback 函数的阻塞方法,例如 fs.readFileSync)会使用 throw 报告错误。
大多数的异步方法都接受一个 callback 函数,该函数会接受一个 Error 对象传入作为第一个参数。
如果第一个参数不是 null 而是一个 Error 实例,则说明发生了错误,应该进行处理。例:

const fs = require('fs');
 fs.readFile('一个不存在的文件', (err, data) => {
 if (err) {
 console.error('读取文件出错!', err);
 return;
 }
 // 否则处理数据
 });

当一个异步方法被一个 EventEmitter 对象调用时,错误会被分发到对象的 ‘error' 事件上。例:

const net = require('net');
 const connection = net.connect('localhost');
 // 添加一个 'error' 事件句柄到一个流:
 connection.on('error', (err) => {
 // 如果连接被服务器重置,或无法连接,或发生任何错误,则错误会被发送到这里。 
 console.error(err);
 });
 connection.pipe(process.stdout);

Node.js API 中有一小部分普通的异步方法仍可能使用 throw 机制抛出异常,且必须使用 try / catch 处理。
这些方法并没有一个完整的列表;请参阅各个方法的文档以确定所需的合适的错误处理机制。
对于所有的 EventEmitter 对象,如果没有提供一个 ‘error' 事件句柄,则错误会被抛出,
并造成 Node.js 进程报告一个未处理的异常且随即崩溃,除非: 适当地使用 domain 模块或已经注册了一个 process.on(‘uncaughtException') 事件的句柄。

const EventEmitter = require('events');
 const ee = new EventEmitter();
 setImmediate(() => {
 // 这会使进程崩溃,因为还为添加 'error' 事件句柄。
 ee.emit('error', new Error('这会崩溃'));
 });

这种方式产生的错误无法使用 try / catch 截获,因为它们是在调用的代码已经退出后抛出的。
开发者必须查阅各个方法的文档以明确在错误发生时这些方法是如何冒泡的。

Error 类

说明:

一个通用的 JavaScript Error 对象,它不表示错误发生的具体情况。
Error 对象会捕捉一个“堆栈跟踪”,详细说明被实例化的 Error 对象在代码中的位置,并可能提供错误的文字描述。
只对于加密,如果在抛出错误时可以使用 Error 对象,则会将OpenSSL错误堆栈放入到名为 opensslErrorStack 的单独属性中。
所有由 Node.js 产生的错误,包括所有系统的和 JavaScript 的错误都实例化自或继承自 Error 类。

new Error(message)

说明:

新建一个 Error 实例,并设置 error.message 属性以提供文本信息。
如果 message 传的是一个对象,则会调用 message.toString() 生成文本信息。
error.stack 属性表示被调用的 new Error() 在代码中的位置。
堆栈跟踪是基于 V8 的堆栈跟踪 API 的。
堆栈跟踪只会取(a)异步代码执行的开头或(b)Error.stackTraceLimit 属性给出的栈帧中的最小项。

demo:

throw new Error('异常信息');
// Error: 异常信息
//  at Object. (/Users/xiaoqiang/Documents/work/demo/NodeApi/app.js:1:69)
//  at Module._compile (module.js:660:30)
//  at Object.Module._extensions..js (module.js:671:10)
//  at Module.load (module.js:573:32)
//  at tryModuleLoad (module.js:513:12)
//  at Function.Module._load (module.js:505:3)
//  at Function.Module.runMain (module.js:701:10)
//  at startup (bootstrap_node.js:193:16)
//  at bootstrap_node.js:617:3

Error.stackTraceLimit

说明:

Error.stackTraceLimit 属性指定了堆栈跟踪收集的栈帧数量
(无论是 new Error().stack 或 Error.captureStackTrace(obj) 产生的)。
默认值为 10 ,但可设为任何有效的 JavaScript 数值。 值改变后的变化会影响所有捕获到的堆栈跟踪。
如果设为一个非数值或负数,则堆栈跟踪不会捕捉任何栈帧。

demo:

Error.stackTraceLimit = 5; 
try{
 const a = 1 + b;
}catch(err){
 console.log(err.stack);
}
// ReferenceError: b is not defined
//  at Object. (/Users/xiaoqiang/Documents/work/demo/NodeApi/app.js:3:16)
//  at Module._compile (module.js:660:30)
//  at Object.Module._extensions..js (module.js:671:10)
//  at Module.load (module.js:573:32)
//  at tryModuleLoad (module.js:513:12)

Error.captureStackTrace(targetObject[, constructorOpt])

说明:

在 targetObject 上创建一个 .stack 属性
当访问时返回一个表示代码中调用 Error.captureStackTrace() 的位置的字符串。
可选的 constructorOpt 参数接受一个函数。 如果提供了,则 constructorOpt 之上包括自身在内的全部栈帧都会被生成的堆栈跟踪省略。

demo:

const myObject = {};
Error.captureStackTrace(myObject);
console.log( myObject.stack ); 
// Error
//  at Object. (/Users/xiaoqiang/Documents/work/demo/NodeApi/app.js:2:7)
//  at Module._compile (module.js:660:30)
//  at Object.Module._extensions..js (module.js:671:10)
//  at Module.load (module.js:573:32)
//  at tryModuleLoad (module.js:513:12)
//  at Function.Module._load (module.js:505:3)
//  at Function.Module.runMain (module.js:701:10)
//  at startup (bootstrap_node.js:193:16)
//  at bootstrap_node.js:617:3

error.code

说明:

error.code 属性是标识错误类别的字符标签。

详见 Node.js Error Codes

demo:
try{
 const a = 1 + b;
}catch(err){
 console.log(err.code);
}
// undefined

error.message

说明:

error.message 属性是错误的字符串描述,通过调用 new Error(message) 设置。
传给构造函数的 message 也会出现在 Error 的堆栈跟踪的第一行。
但是,Error 对象创建后改变这个属性可能不会改变堆栈跟踪的第一行(比如当 error.stack 在该属性被改变之前被读取)。

demo:

try{
 const a = 1 + b;
}catch(err){
 console.log(err.message);
}
// b is not defined

error.stack

说明:

error.stack 属性是一个字符串,描述代码中 Error 被实例化的位置。

第一行会被格式化为 : ,
且带上一系列栈帧(每一行都以 “at ” 开头)。 每一帧描述了一个代码中导致错误生成的调用点。
V8 引擎会试图显示每个函数的名称(变量名、函数名、或对象的方法名),但偶尔也可能找不到一个合适的名称。
如果 V8 引擎没法确定一个函数的名称,则只显示帧的位置信息。 否则,在位置信息的旁边会显示明确的函数名。
注意,帧只由 JavaScript 函数产生。

demo:

try{
 const a = 1 + b;
}catch(err){
 console.log(err.stack);
}
// ReferenceError: b is not defined
//  at Object. (/Users/xiaoqiang/Documents/work/demo/NodeApi/app.js:2:16)
//  at Module._compile (module.js:660:30)
//  at Object.Module._extensions..js (module.js:671:10)
//  at Module.load (module.js:573:32)
//  at tryModuleLoad (module.js:513:12)
//  at Function.Module._load (module.js:505:3)
//  at Function.Module.runMain (module.js:701:10)
//  at startup (bootstrap_node.js:193:16)
//  at bootstrap_node.js:617:3

AssertionError 类

说明:

Error 的子类,表示断言失败。 这种错误通常表示实际值和预期值不相等。

demo:

const assert = require('assert');
assert.strictEqual(1, 2);
// AssertionError [ERR_ASSERTION]: 1 === 2

RangeError 类

说明:

Error 的一个子类,表明一个函数的一个给定的参数的值不在可接受的集合或范围内;
无论是一个数字范围还是给定函数参数的选项的集合。

demo:

require('net').connect(-1);
// RangeError [ERR_SOCKET_BAD_PORT]: Port should be > 0 and < 65536. Received -1.

ReferenceError 类

说明:

Error 的一个子类,表明试图访问一个未定义的变量。 这些错误通常表明代码有拼写错误或程序已损坏。
虽然客户端代码可能产生和传播这些错误,但在实践中,只有 V8 引擎会这么做。

demo:

console.log( a );
// ReferenceError: a is not defined

SyntaxError 类

说明:

Error 的一个子类,表明程序不是有效的 JavaScript 代码。 这些错误是代码执行的结果产生和传播的。
代码执行可能产生自 eval、Function、require 或 vm。 这些错误几乎都表明程序已损坏。

demo:

eval('**');
// SyntaxError: Unexpected token **

TypeError 类

说明:

Error 的一个子类,表明提供的参数不是一个被允许的类型。
例如,将一个函数传给一个期望字符串的参数会被视为一个 TypeError。

demo:

require('url').parse(() => { });
// TypeError [ERR_INVALID_ARG_TYPE]: The "url" argument must be of type string. Received type function

System Error 类

说明:

系统错误是当程序运行环境中发生异常时产生的。
有单独的异常类,并且有单独的属性:
error.code属性是一个表示错误码的字符串,总是 E 带上一串大写字母。
error.errno属性是一个数值或字符串。 如果返回一个数值,则数值是一个负数,
对应 libuv 错误处理 中定义的错误码。 如果返回一个字符串,则同 error.code。
error.syscall属性是一个字符串,描述失败的 系统调用。
error.path属性是一个字符串,包含了相关不可用路径名。
error.address属性是对链接失败的地址的描述。
error.port是一个链接端口不可用的端口值

异常与错误

说明:

JavaScript 异常是一个作为一个无效操作的结果或作为一个 throw 声明的目标所抛出的值。
虽然它不要求这些值是 Error 的实例或继承自 Error 的类的实例,
但所有通过 Node.js 或 JavaScript 运行时抛出的异常都是 Error 实例。
有些异常在 JavaScript 层是无法恢复的。 这些异常总会引起 Node.js 进程的崩溃。
例如 assert() 检测或在 C++ 层调用的 abort()。

系统错误

说明:

系统错误是当程序运行环境中发生异常时产生的。
特别是,当应用程序违反了操作系统的限制时发生的操作错误,例如试图读取一个不存在的文件或用户没有足够的权限。
系统错误通常产生于系统调用层级。
在大多数 Unix 系统上,可通过运行 man 2 intro、man 3 errno、或在线文档获取错误代码的详细清单和含义。
系统错误是由扩展的 Error 对象加上附加属性表现的。

常见的系统错误:

以下列表是不完整的,但列举了编写 Node.js 程序时会遇到的一些常见的系统错误。 详细的列表可从 ERRNO 文档找到。
EACCES (拒绝访问): 试图以被一个文件的访问权限禁止的方式访问一个文件。

EADDRINUSE (地址已被使用): 试图绑定一个服务器(net、http 或 https)到本地地址,但因另一个本地系统的服务器已占用了该地址而导致失败。

ECONNREFUSED (连接被拒绝): 无法连接,因为目标机器积极拒绝。 这通常是因为试图连接到外部主机上的废弃的服务。

ECONNRESET (连接被重置): 一个连接被强行关闭。 这通常是因为连接到远程 socket 超时或重启。 常发生于 http 和 net 模块。

EEXIST (文件已存在): 一个操作的目标文件已存在,而要求目标不存在。

EISDIR (是一个目录): 一个操作要求一个文件,但给定的路径是一个目录。

EMFILE (系统打开了太多文件): 已达到系统文件描述符允许的最大数量,且描述符的请求不能被满足直到至少关闭其中一个。 当一次并行打开多个文件时会发生这个错误,尤其是在进程的文件描述限制数量较低的操作系统(如 macOS)。 要解决这个限制,可在运行 Node.js 进程的同一 shell 中运行 ulimit -n 2048。

ENOENT (无此文件或目录): 通常是由 fs 操作引起的,表明指定的路径不存在,即给定的路径找不到文件或目录。

ENOTDIR (不是一个目录): 给定的路径虽然存在,但不是一个目录。 通常是由 fs.readdir 引起的。

ENOTEMPTY (目录非空): 一个操作的目标是一个非空的目录,而要求的是一个空目录。 通常是由 fs.unlink 引起的。

EPERM (操作不被允许): 试图执行一个需要更高权限的操作。

EPIPE (管道损坏): 写入一个管道、socket 或 FIFO 时没有进程读取数据。 常见于 net 和 http 层,表明远端要写入的流已被关闭。

ETIMEDOUT (操作超时): 一个连接或发送的请求失败,因为连接方在一段时间后没有做出合适的响应。 常见于 http 或 net。 往往标志着 socket.end() 没有被正确地调用

希望本文所述对大家node.js程序设计有所帮助。

Javascript 相关文章推荐
用javascript动态调整iframe高度的代码
Apr 10 Javascript
Javascript &amp; DHTML 实例编程(教程)DOM基础和基本API
Jun 02 Javascript
Prototype RegExp对象 学习
Jul 19 Javascript
封装html的select标签的js操作实例
Jul 02 Javascript
FireBug 调试JS入门教程 如何调试JS
Dec 23 Javascript
jQuery对于显示和隐藏等常用状态的判断方法
Dec 13 Javascript
javascript 判断是否是微信浏览器的方法
Oct 09 Javascript
详解关于react-redux中的connect用法介绍及原理解析
Sep 11 Javascript
Element Input组件分析小结
Oct 11 Javascript
JavaScript实现图片放大镜效果
Jun 27 Javascript
Vue+elementUI实现多图片上传与回显功能(含回显后继续上传或删除)
Mar 23 Javascript
vue 使用lodash实现对象数组深拷贝操作
Sep 10 Javascript
微信小程序 获取手机号 JavaScript解密示例代码详解
May 14 #Javascript
JavaScript, select标签元素左右移动功能实现
May 14 #Javascript
vue实现商品列表的添加删除实例讲解
May 14 #Javascript
Vue 自适应高度表格的实现方法
May 13 #Javascript
ES6函数实现排它两种写法解析
May 13 #Javascript
详解vue-router的Import异步加载模块问题的解决方案
May 13 #Javascript
JavaScript 实现自己的安卓手机自动化工具脚本(推荐)
May 13 #Javascript
You might like
不重新编译PHP为php增加openssl模块的方法
2011/06/14 PHP
phpphp图片采集后按原路径保存图片示例
2014/02/18 PHP
php一行代码获取文件后缀名实例分析
2014/11/12 PHP
PHP实现的迷你漂流瓶
2015/07/29 PHP
PHP给源代码加密的几种方法汇总(推荐)
2018/02/06 PHP
JS 跳转页面延迟2种方法
2013/03/29 Javascript
Javascript实现滑块滑动改变值的实现代码
2013/04/12 Javascript
『jQuery』名称冲突使用noConflict方法解决
2013/04/22 Javascript
jquery中filter方法用法实例分析
2015/02/06 Javascript
JavaScript中的splice方法用法详解
2016/07/20 Javascript
BootStrap 实现各种样式的进度条效果
2016/12/07 Javascript
canvas实现爱心和彩虹雨效果
2017/03/09 Javascript
微信小程序-滚动消息通知的实例代码
2017/08/03 Javascript
深入理解Vue 的条件渲染和列表渲染
2017/09/01 Javascript
使用Python编写一个在Linux下实现截图分享的脚本的教程
2015/04/24 Python
Python自定义类的数组排序实现代码
2016/08/28 Python
利用python获取当前日期前后N天或N月日期的方法示例
2017/07/30 Python
python基础知识(一)变量与简单数据类型详解
2019/04/17 Python
简单了解python PEP的一些知识
2019/07/13 Python
Python IDE Pycharm中的快捷键列表用法
2019/08/08 Python
基于django ManyToMany 使用的注意事项详解
2019/08/09 Python
python实现把二维列表变为一维列表的方法分析
2019/10/08 Python
python3下pygame如何实现显示中文
2020/01/11 Python
详解基于python的图像Gabor变换及特征提取
2020/10/26 Python
找到您丢失的钥匙、钱包和手机:Tile
2017/05/19 全球购物
几个判断型的面试题
2012/07/03 面试题
成人教育自我鉴定
2013/11/01 职场文书
校园网站的创业计划书范文
2013/12/30 职场文书
三八妇女节致辞
2015/07/31 职场文书
生日寿星公答谢词
2015/09/29 职场文书
2016干部作风整顿心得体会
2016/01/22 职场文书
2016年圣诞节义工活动总结
2016/04/01 职场文书
党组织关系的介绍信模板
2019/06/21 职场文书
golang 实现两个结构体复制字段
2021/04/28 Golang
Python绘制地图神器folium的新人入门指南
2021/05/23 Python
Oracle查看表空间使用率以及爆满解决方案详解
2022/07/23 Oracle