【每日一题】Node错误拦截的几种方式
人生苦短,总需要一点仪式感。比如学前端~
Node原生api错误处理
1、不接受callback的同步API,使用JS的try…catch
捕获throw抛出的错误;
2、接受callback函数的异步方法使用第一个参数的Error对象
获取,若第一个参数不是null则应该处理错误;
3、在EventEmitter对象上调用异步方法,可以监听error事件
触发来捕获错误。
nodeJS 应用程序一般会遇到以下四类错误:
标准的JS错误。例如
<EvalError>
、<SyntaxError>
、<RangeError>
、<ReferenceError>
、<TypeError>
或<URIError>
。由底层操作系统触发的系统错误。例如:试图打开不存在的文件或者试图更新已关闭的 socket 发送数据
由应用程序代码触发的用户自定义的错误。
AssertionError错误,当 Node.js 检测到不应该发生的异常逻辑时触发。这类错误通常来自assert模块。
所有由 nodeJS 引起的 JavaScript 错误与系统错误(前两种错误)都继承或实例化标准的 JavaScript <Error>类
,并保证至少提供类中的属性。
错误捕获与处理
Node.js 支持多种机制来传播和处理应用程序运行时发生的错误。如何报告和处理这些错误完全取决于 Error 的类型和调用的 API 的风格。
js错误:throw抛出、try catch捕获
所有的 JavaScript 错误都作为异常处理,使用标准的 JavaScript throw
机制立即生成并抛出错误。这些是使用 JavaScript 语言提供的 try…catch
构造处理的。
// 由于 z 未定义,因此抛出 ReferenceError。
try {
const m = 1;
const n = m + z;
} catch (err) {
// 在此捕获并处理错误。
}
throw 机制触发的异常,必须使用 try…catch 处理,否则 Node.js 进程将立即退出。
同步无回调API:throw抛出、try catch捕获
除了少数例外,同步的 API(任何不接受 callback 函数的阻塞方法,例如 fs.readFileSync
)会使用 throw 报错,同上边,用 try…catch
捕获。
异步API
异步的 API 中发生的错误可能会以多种方式进行报告:
接受callback回调:第一个参数传递错误内容
Node.js 核心 API 暴露的大多数异步方法都遵循称为错误优先回调的惯用模式。
“错误优先”:回调函数的第一个参数是Error错误实例对象(没有错误时值为null),第二个才是响应结果。
const fs = require('fs');
fs.readFile('a file that does not exist', (err, data) => {
// 回调函数必须是“错误优先”的,第一个参数是触发错误时传递的内容
if (err) {
// 第一个参数不是 null 而是一个 Error 实例,则说明发生了错误,应该进行处理。
console.error('There was an error reading the file!', err);
return;
}
// 否则处理数据
});
EventEmitter:触发error事件,error事件监听器捕获
当 EventEmitter 实例中发生错误时,典型的操作是触发 'error' 事件。
因此在 EventEmitter 对象上调用异步方法时,我们可以对该对象的 'error' 事件进行监听。
设置error事件监听器来捕获该异常:
const net = require('net');
const connection = net.connect('localhost');
// 向流中添加 'error' 事件监听器:
connection.on('error', (err) => {
// 如果连接被服务器重置,
// 或者根本无法连接,或者连接遇到任何类型的错误,
// 则错误将发送到这里。
console.error(err);
});
connection.pipe(process.stdout);
如果没有为 'error' 事件注册至少一个监听器:触发 'error' 事件后就会抛出错误、打印堆栈跟踪、然后退出 Node.js 进程。
'error' 事件机制的使用最常见于基于流和基于事件触发器的 API,其本身代表了一系列随时间推移的异步操作(而不是单个操作可能通过或失败)。
TIPS:
NodeJS API 中有一小部分普通的异步方法仍可能使用 throw 机制抛出异常,且必须使用 try...catch...处理。需要根据具体的API文档约定来处理。
让我们一起携手同走前端路!
关注公众号回复【加群】即可