nodejs中的错误类型及捕获处理
在 node
中,提供了 error
模块,并且内置了标准的 JavaScript
错误,本文将介绍在node
中错误类型以及如何捕获。
错误类型
js错误
标准的js
错误,跟在浏览器中运行js
时提示的错误类型一样
RangeError
当一个值不在其所允许的范围或者集合中。
例如不能将数字的有效位数位 1-100,将其设置为 200 就出现RangeError
错误。
const num = 1;
num.toPrecision(200);
ReferenceError
引用未声明的变量。
console.log(undefinedVariable);
SyntaxError
解析时发生语法错误。
一般SyntaxError
在构建阶段,甚至本地开发阶段就会被发现。
constt a;
lett b;
varr c;
TypeError
值类型不对,当传入函数的操作数或参数的类型并非操作符或函数所预期的类型时,将抛出一个 TypeError
类型错误。
const nul = null;
console.log(null.value);
URIError
URI
函数被错误使用时抛出(比如字符串包含了%
字符,执行decodeURIComponent
时就会报错)
console.log(decodeURIComponent("https:/example.com%"));
EvalError
调用eval()
失败时抛出
系统错误
系统错误是对JavaScript
错误Error
对象的一个扩展,它们表示程序能够处理的操作错误,这些错误信息都是在系统级别生成的(比如我们想打开一个文件,但是系统中不存在这个文件,就会抛出系统错误)。
const fs = require("fs");
fs.readFile("/null", (err, data) => {if (err) console.log(err);else console.log(data);
});
assert断言错误
通过 assert
模块抛出的错误。
const assert = require("assert");
const a = 1;
assert(a > 10, "a不能小于10");
console.log("last");
自定义错误
通过throw
手动抛出错误:
const a =1;
if(a < 2) {throw Error('小于2')
}
捕获处理
同步代码
同步代码中的异常使用try...catch
结构即可捕获处理。
try {throw new Error('error');
} catch (e) {console.error(e.message);
}
异步代码
使用回调函数
不过大多数Node.js
核心API
都提供了回调函数来处理错误,比如:
const fs = require("fs");
fs.readFile("/null", (err, data) => {if (err) console.log(err);else console.log(data);
});
通过回调函数的err
参数来检查是否出现错误,再进行处理。Node.js
之所以采用这种错误处理机制,是因为异步方法所产生的方法并不能简单地通过try...catch
机制进行拦截。
如果在程序执行过程中出现了未捕获的异常,那么程序就会崩溃,因此先把错误进行捕获后传递到回调函数中,就不会让程序奔溃,后续代码也能被顺利运行
使用process模块
因为异常并不是事先准备好的,不能控制其到底在哪儿发生,所以我们可以通过监听应用进程的错误异常,从而捕获到不能预料的错误异常,保证应用不至于奔溃。
process.on('uncaughtException', (e)=>{console.error('process error is:', e.message);
});
通过使用process
模块监听uncaughtException
事件,可以捕获到整个进程包含异步中的错误信息。
当异常出现时,对应执行栈中断,process
捕获的异常事件导致v8
引擎的垃圾回收功能不能按照正常流程工作,然后开始出现内存泄漏问题。
相对于异常来说,内存泄漏也是一个不能忽视的严重问题,而process.on('uncaughtException')
的做法,很难去保证不造成内存的泄漏。所以当捕获到异常时,显式的手动杀掉进程,并开始重启node
进程,即保证释放内存,又保证了保证服务后续正常可用。
process.on('uncaughtException', (e)=>{console.error('process error is:', e.message);process.exit(1);restartServer(); // 重启服务
});