我想编写一个通用的错误处理程序,它将捕获在代码的任何实例中故意抛出的自定义错误。
当我抛出新的错误('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将终止进一步的执行并在捕获错误时暴露消息字符串。
尝试{
投掷“我是邪恶的”
console.log("你永远也找不到我",123465)
} catch (e) {
console.log (e);//我是邪恶的
}
抛出后将永远无法到达控制台,导致终止。
抛出新的错误("I'm Evil")
暴露一个带有两个参数名称和消息的错误事件。它还会终止进一步的执行
尝试{
抛出新的错误("I'm Evil")
console.log("你永远也找不到我",123465)
} catch (e) {
console.log (e.name e.message);//错误I'm Evil
}
抛出错误("I'm Evil")
为了完整起见,这个也可以,虽然技术上不是正确的方法
尝试{
抛出错误("I'm Evil")
console.log("你永远也找不到我",123465)
} catch (e) {
console.log (e.name e.message);//错误I'm Evil
}
console.log(typeof(新的错误("hello"))) //对象
console.log(typeof(Error)) //函数
的反应行为
除了其他的答案,我还想说明React的一个不同之处。
如果我抛出一个新的Error(),并且我处于开发模式,我将得到一个错误屏幕和一个控制台日志。如果我抛出一个字符串字面量,我只会在控制台中看到它,如果我没有观察控制台日志,可能会错过它。
例子
在开发模式下向控制台抛出错误日志并显示错误屏幕(在生产环境中不可见)。
throw new Error("The application could not authenticate.");
而下面的代码只能登录到控制台:
throw "The application could not authenticate.";
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');
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”,然后随后捕获并处理。