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 相关文章推荐
js、css、img等浏览器缓存问题的2种解决方案
Oct 23 Javascript
jQuery点击自身以外地方关闭弹出层的简单实例
Dec 24 Javascript
jQuery中slice()方法用法实例
Jan 07 Javascript
JavaScript为事件句柄绑定监听函数实例详解
Dec 15 Javascript
js关于getImageData跨域问题的解决方法
Oct 14 Javascript
JavaScript将base64图片转换成formData并通过AJAX提交的实现方法
Oct 24 Javascript
BootStrap组件之进度条的基本用法
Jan 19 Javascript
JS字符串false转boolean的方法(推荐)
Mar 08 Javascript
vue 如何添加全局函数或全局变量以及单页面的title设置总结
Jun 01 Javascript
Angular指令之restict匹配模式的详解
Jul 27 Javascript
微信小程序request请求后台接口php的实例详解
Sep 20 Javascript
JS实现换肤功能的方法实例详解
Jan 30 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版
2012/04/20 PHP
用php来限制每个ip每天浏览页面数量的实现思路
2015/02/24 PHP
CentOS安装php v8js教程
2015/02/26 PHP
php快速查找数据库中恶意代码的方法
2015/04/01 PHP
php使用正则表达式去掉html中的注释方法
2016/11/03 PHP
在IE上直接编辑网页内容的js代码(IE地址栏js)
2009/04/27 Javascript
DIY jquery plugin - tabs标签切换实现代码
2010/12/11 Javascript
Document:getElementsByName()使用方法及示例
2013/10/28 Javascript
jquery和css3实现的炫酷时尚的菜单导航
2014/09/01 Javascript
VS2008中使用JavaScript调用WebServices
2014/12/18 Javascript
javascript判断变量是否有值的方法
2015/04/20 Javascript
轻松学习jQuery插件EasyUI EasyUI表单验证
2015/12/01 Javascript
详解Jquery实现ready和bind事件
2016/04/14 Javascript
概述如何实现一个简单的浏览器端js模块加载器
2016/12/07 Javascript
js插件实现图片滑动验证码
2020/09/29 Javascript
用Node提供静态文件服务的方法
2018/07/06 Javascript
vue 的点击事件获取当前点击的元素方法
2018/09/15 Javascript
详解多页应用 Webpack4 配置优化与踩坑记录
2018/10/16 Javascript
python 获取sqlite3数据库的表名和表字段名的实例
2019/07/17 Python
详解Python中字符串前“b”,“r”,“u”,“f”的作用
2019/12/18 Python
通过Python扫描代码关键字并进行预警的实现方法
2020/05/24 Python
python能做哪方面的工作
2020/06/15 Python
python环境搭建和pycharm的安装配置及汉化详细教程(零基础小白版)
2020/08/19 Python
关于python3.9安装wordcloud出错的问题及解决办法
2020/11/02 Python
解决virtualenv -p python3 venv报错的问题
2021/02/05 Python
html5 Canvas画图教程(3)—canvas出现1像素线条模糊不清的原因
2013/01/09 HTML / CSS
德国大型的家具商店:Pharao24.de
2016/10/02 全球购物
在数据文件自动增长时,自动增长是否会阻塞对文件的更新
2014/05/01 面试题
工作岗位说明书模板
2014/05/09 职场文书
演讲开场白台词大全
2015/05/29 职场文书
社区挂职锻炼个人工作总结
2015/10/23 职场文书
2016年基层党组织公开承诺书
2016/03/25 职场文书
《家》读后感:万惜拯救,冷暖自知
2019/09/25 职场文书
导游词之青城山景区
2019/09/27 职场文书
利用html+css实现菜单栏缓慢下拉效果的示例代码
2021/03/30 HTML / CSS
简述Java中throw-throws异常抛出
2021/08/07 Java/Android