我想编写一个通用的错误处理程序,它将捕获在代码的任何实例中故意抛出的自定义错误。
当我抛出新的错误('sample'),如下所示
try {
throw new Error({'hehe':'haha'});
// throw new Error('hehe');
} catch(e) {
alert(e);
console.log(e);
}
日志在Firefox中显示为错误:[object object],我无法解析该对象。
对于第二次抛出,日志显示为:错误:呵呵
然而当我这样做的时候
try {
throw ({'hehe':'haha'});
} catch(e) {
alert(e);
console.log(e);
}
控制台显示为:对象{hehe="haha"},我可以在其中访问错误属性。
有什么不同?
区别是否如代码中所示?比如字符串会作为字符串传递而对象作为对象但语法会有所不同?
我还没有探索过抛出错误对象…我只抛出了字符串。
除了以上两种方法,还有别的办法吗?
throw new Error()用于抛出指定的错误。但如果你想做自定义错误处理,最好使用throw {example: 'error'}。
也就是说,如果你想知道指定的错误,使用throw new error ("example string"),如果你想自定义处理错误,使用throw。
function makeErrorResponse(err = {}, httpStatus, status, message, message) {
const error = new Error();
error.httpStatus = httpStatus;
error.status = status;
error.message = message;
error.err = err;
return error;
}
throw makeErrorResponse({}, 500, 500, 'server error');
'throw new Error'和'throw someObject'在javascript中的区别在于,throw new Error将传递给它的错误以以下格式包装
{name: '错误',消息:'传入构造函数的字符串'
}
throw someObject将按原样抛出对象,并且不允许从try块执行任何进一步的代码,即与throw new Error相同。
下面是关于Error对象和抛出自己的错误的一个很好的解释
错误对象
在发生错误时,我们能从中提取什么?所有浏览器中的Error对象都支持以下两个属性:
name:错误的名称,或者更具体地说,错误所属的构造函数的名称。
message:错误的描述,该描述因浏览器而异。
name属性可以返回六个可能的值,如前所述,它对应于错误构造函数的名称。它们是:
Error Name Description
EvalError An error in the eval() function has occurred.
RangeError Out of range number value has occurred.
ReferenceError An illegal reference has occurred.
SyntaxError A syntax error within code inside the eval() function has occurred.
All other syntax errors are not caught by try/catch/finally, and will
trigger the default browser error message associated with the error.
To catch actual syntax errors, you may use the onerror event.
TypeError An error in the expected variable type has occurred.
URIError An error when encoding or decoding the URI has occurred
(ie: when calling encodeURI()).
抛出自己的错误(异常)
在控制自动从try块转移到catch块之前,您不必等待6种类型错误中的一种发生,还可以显式地抛出自己的异常,以强制按需发生这种情况。这对于创建关于错误是什么以及何时应该将控制转移到catch的定义非常有用。
下面的文章可能会更详细地说明哪个是更好的选择;throw 'An error'或throw new error ('An error'):
http://www.nczonline.net/blog/2009/03/10/the-art-of-throwing-javascript-errors-part-2/
它表明后者(new Error())更可靠,因为像Internet Explorer和Safari(不确定版本)这样的浏览器在使用前者时不能正确地报告消息。
这样做将导致抛出错误,但并非所有浏览器都以您期望的方式响应。Firefox, Opera和Chrome都显示一个“未捕获的异常”消息,然后包含消息字符串。Safari和Internet Explorer只是抛出一个“未捕获的异常”错误,根本不提供消息字符串。显然,从调试的角度来看,这是次优的。
TLDR
throw new Error('problem')捕获错误发生位置的许多属性。
抛出“问题”则不然
new Error('message')捕获执行堆栈+其他
使用Error对象允许您在抛出错误时捕获执行堆栈。因此,当错误被传递到错误处理树时,这个堆栈快照也会被传递。
因此,在我的代码库中插入throw“test error”会导致:
而throw new Error('test Error ')会导致:
您可以看到本机Error对象在抛出错误时捕获堆栈,并使捕获错误的任何对象都可以使用它。这使我在调试时更容易跟踪问题。
除此之外,它还捕获诸如fileName、lineNumber和columnNumber等属性。
如果您使用堆栈跟踪,则异常跟踪器将为您记录日志
在这种情况下,堆栈将被打印到浏览器控制台,但如果你使用的是Javascript错误记录工具,如Appsignal或Bugsnag,那么堆栈也将在它们中可用。如果你检查错误对象,你可以直接访问堆栈快照:
err = new Error('test')
err.stack
我用来决定使用哪种格式的启发式方法
当我不打算捕获异常时,我使用new Error('problem')
当我抛出一个错误,因为应用程序中发生了一些意想不到的或超出范围的事情,假设本地数据存储损坏了,我可能不想处理它,但我确实想标记它。在本例中,我将使用Error对象,这样我就有了堆栈快照。
通过使用throw new Error('Datastore is corrupt '),更容易追踪到所发生的事情。
当我计划捕获异常时,我使用抛出'problem'
在重新阅读这篇文章时,我认为下一部分需要一些谨慎。通常,非常具体地说明要捕获的错误是一个好主意,否则您可能会捕获您真正想要一直冒泡的东西。一般来说,创建特定的错误类型并捕获特定的错误(或消息字符串)可能更好。这使得你没有预料到的错误浮出水面。”
如果错误是我计划捕获和处理的预期错误,那么我将不会从堆栈快照中得到太多用处。
假设我使用一个http服务,它返回一个500的http代码。我可以将此视为一个错误,我抛出“responseccode =500”,然后随后捕获并处理。