还有很重要的一点值得注意,那就是我们甚至可以大可不必抛出Error对象。尽管这看起来非常cool且非常自由,但实际并非如此,尤其是对开发第三方库的开发者来说,因为他们必须处理用户(使用库的开发者)的代码。由于缺乏标准,他们并不能把控用户的行为。你不能相信用户并简单的抛出一个Error对象,因为他们不一定会那么做而是仅仅抛出一个字符串或者数字(鬼知道用户会抛出什么)。这也使得处理必要的堆栈跟踪和其他有意义的元数据变得更加困难。
假设有以下代码:
function runWithoutThrowing(func) {
try {
func();
} catch (e) {
console.log('There was an error, but I will not throw it.');
console.log('The error\'s message was: ' + e.message)
}
}
function funcThatThrowsError() {
throw new TypeError('I am a TypeError.');
}
runWithoutThrowing(funcThatThrowsError);
如果你的用户像上面这样传递一个抛出Error对象的函数给runWithoutThrowing函数(那就谢天谢地了),然而总有些人偷想懒直接抛出一个String,那你就麻烦了:
function runWithoutThrowing(func) {
try {
func();
} catch (e) {
console.log('There was an error, but I will not throw it.');
console.log('The error\'s message was: ' + e.message)
}
}
function funcThatThrowsString() {
throw 'I am a String.';
}
runWithoutThrowing(funcThatThrowsString);
现在第二个console.log会打印出 the error’s message is undefined.这么看来也没多大的事(后果)呀,但是如果您需要确保某些属性存在于Error对象上,或以另一种方式(例如Chai的throws断言 does))处理Error对象的特定属性,那么你做需要更多的工作,以确保它会正常工资。
此外,当抛出的值不是Error对象时,你无法访问其他重要数据,例如stack,在某些环境中它是Error对象的一个属性。
Errors也可以像其他任何对象一样使用,并不一定非得要抛出他们,这也是它们为什么多次被用作回调函数的第一个参数(俗称 err first)。 在下面的fs.readdir()例子中就是这么用的。
const fs = require('fs');
fs.readdir('/example/i-do-not-exist', function callback(err, dirs) {
if (err instanceof Error) {
// `readdir` will throw an error because that directory does not exist
// We will now be able to use the error object passed by it in our callback function
console.log('Error Message: ' + err.message);
(责任编辑:admin)