使用 coffeescript/javascript 'throw error' 或 'throw new Error(error)'?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10977120/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 11:41:23  来源:igfitidea点击:

Use coffeescript/javascript 'throw error' or 'throw new Error(error)'?

javascripterror-handlingcoffeescript

提问by Mihai Oprea

I have the following coffeescript code:

我有以下咖啡脚本代码:

try
   do something
catch error
   log something
   throw error

Should I use throw new Error(error)instead of throw error?

我应该使用throw new Error(error)而不是throw error吗?

What is the difference?

有什么区别?

回答by Andrew Андрей Листочкин

Same as in other languages like C# or Java:

与 C# 或 Java 等其他语言相同:

  • throw errorthrows the same Error object
  • throw new Error(error)wraps it into a new Error object. The later is used, for example, in Java when you need to convert checked Exceptioninto unchecked one. In JavaScript you don't need to wrap exceptions as this would make stacktrace a bit longer and less pretty.
  • throw error抛出相同的 Error 对象
  • throw new Error(error)将其包装成一个新的 Error 对象。后者用于,例如,在 Java 中,当您需要将已检查的异常转换为未检查的异常时。在 JavaScript 中,您不需要包装异常,因为这会使堆栈跟踪变得更长且不那么漂亮。

Edit: There're some security implications as well. Here's an example:

编辑:还有一些安全隐患。下面是一个例子:

function noWrap() {
    try {
        var o = {}; o.nonexistingMethod();
    } catch (error) {
        throw error;
    }
}

function wrap() {
    try {
        var o = {}; o.nonexistingMethod();
    } catch (error) {
        throw new Error(error);
    }
}

Calling noWrap()produces the following error message:

调用noWrap()会产生以下错误消息:

"TypeError: Object #<Object> has no method 'nonexistingMethod'"
// with error.arguments === ['nonexistingMethod', o]

Calling wrap()produces the following error message:

调用wrap()会产生以下错误消息:

"Error: TypeError: Object #<Object> has no method 'nonexistingMethod'"
//  with error.arguments === undefined

So, as you can see by using a wrapping Error object we can hide the argumentsof original error. Suppose you're writing one of the following:

因此,正如您所看到的,通过使用包装 Error 对象,我们可以隐藏arguments原始错误。假设您正在编写以下内容之一:

  • some kind of a library
  • a script which will be loaded on a page that you don't own (for example, some kind of like or tweet button)
  • a script on a page that has some third-party scripts loaded (social buttons, ads, tracking code, etc.)
  • 某种图书馆
  • 将加载到您不拥有的页面上的脚本(例如,某种喜欢或推文按钮)
  • 页面上加载了一些第三方脚本(社交按钮、广告、跟踪代码等)的脚本

In all those cases listed above in order to stay secure you should wrap yourErrorobjects. Otherwise you may accidentally leak references to your internal objects, functions and variables.

在上面列出的所有这些情况下,为了保持安全,您应该包装您的Error对象。否则,您可能会意外泄漏对内部对象、函数和变量的引用。

Edit 2: Regarding stacktraces. Both variants preserve them. Here's a working exampleand I get the following stacktraces in Chrome:

编辑 2:关于堆栈跟踪。两种变体都保留了它们。这是一个工作示例,我在 Chrome 中得到以下堆栈跟踪:

// No wrapping:
TypeError: Object #<Object> has no method 'nonexistingMethod'
    at noWrap (http://fiddle.jshell.net/listochkin/tJzCF/show/:22:23)
    at http://fiddle.jshell.net/listochkin/tJzCF/show/:37:5
    at http://fiddle.jshell.net/js/lib/mootools-core-1.4.5-nocompat.js:3901:62
    at http://fiddle.jshell.net/js/lib/mootools-core-1.4.5-nocompat.js:3915:20

// Wrapping:
Error: TypeError: Object #<Object> has no method 'nonexistingMethod'
    at wrap (http://fiddle.jshell.net/listochkin/tJzCF/show/:32:15)
    at http://fiddle.jshell.net/listochkin/tJzCF/show/:44:5
    at http://fiddle.jshell.net/js/lib/mootools-core-1.4.5-nocompat.js:3901:62
    at http://fiddle.jshell.net/js/lib/mootools-core-1.4.5-nocompat.js:3915:20