我想编写一个常见的错误处理程序,它将捕获任何代码实例上出现的自定义错误。
当我在以下代码中执行throw new Error('sample')
时
try {
throw new Error({'hehe':'haha'});
// throw new Error('hehe');
} catch(e) {
alert(e);
console.log(e);
}
日志在Firefox中显示为Error: [object Object]
,我无法解析该对象。
对于第二个throw
,日志显示为:Error: hehe
而当我做的时候
try {
throw ({'hehe':'haha'});
} catch(e) {
alert(e);
console.log(e);
}
控制台显示为:Object { hehe="haha"}
,我可以在其中访问错误属性。
有什么区别?
代码中是否存在差异?像字符串一样,它将作为字符串和对象作为对象传递,但语法会有所不同吗?
我没有探索过抛出错误对象......我只是扔了字符串。
除上述两种方法外还有其他方法吗?
答案 0 :(得分:192)
以下是The Error object and throwing your own errors
的一个很好的解释错误对象
我们可以在发生错误时从中提取出来的内容?所有浏览器中的Error对象都支持以下两个属性:
name:错误的名称,或者更具体地说,是错误所属的构造函数的名称。
消息:错误的描述,此描述因浏览器而异。
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。
答案 1 :(得分:66)
以下文章可能会更详细地说明哪个是更好的选择; 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只是抛出“未捕获的异常”错误,并且根本不提供消息字符串。显然,从调试的角度来看,这是次优的。
答案 2 :(得分:59)
投掷终止进一步执行&在 catch 错误上公开消息字符串。
try{
throw 'I\'m Evil'
console.log('You\'ll never reach to me', 123465)
}
catch(e){
console.log(e); //I\'m Evil
}
抛出之后的控制台永远不会达到终止的原因。
抛出新错误使用两个参数名称&曝光错误事件的消息即可。它还终止了进一步的执行
try{
throw new Error('I\'m Evil')
console.log('You\'ll never reach to me', 123465)
}
catch(e){
console.log(e.name, e.message); //Error, I\'m Evil
}
答案 3 :(得分:28)
您首先提到此代码:
throw new Error('sample')
然后在你的第一个例子中写下:
throw new Error({'hehe':'haha'})
第一个Error对象实际上会起作用,因为它需要一个字符串值,在本例中为' sample'。第二个不会,因为你试图传入一个对象,它期待一个字符串。
错误对象会有"消息"财产,这将是'样本'。
答案 4 :(得分:3)
您可以throw
作为对象
throw ({message: 'This Failed'})
然后例如在您的try/catch
try {
//
} catch(e) {
console.log(e); //{message: 'This Failed'}
console.log(e.message); //This Failed
}
或者只是抛出一个字符串错误
throw ('Your error')
try {
//
} catch(e) {
console.log(e); //Your error
}
throw new Error //only accept a string
答案 5 :(得分:3)
这已经很老了,但希望任何搜索此内容的人仍然可以从中学习:
首先也是著名的,在 javascript 中,我们有一个叫做 Primitive Wrapper 的东西;原始包装器采用原始数据并通过简单地使用“构造函数模式”以对象格式表示它。然而,在原始包装器中,您可以决定将数据作为对象类型返回,也可以将其作为原始类型返回(在这种情况下,您现在可以使用 javascript 的 go-ahead 命令来提取原始值在这种情况下,您不使用 new 关键字)。
总结:
throw "My error":这将创建一个 Error 对象并返回从构造函数 "this" 对象中提取的原始数据。如果您尝试检查 catch 块中的 typeof,它会告诉您它是原始类型的“字符串”
throw new Error("My error"):这会返回一个对象,您可以在其中访问消息属性中的错误值。这里发生的事情是“新关键字”构造了一个“this”对象并将“{name:"Error",message:"..."}”分配给它并返回它。当您尝试从 catch 块检查 typeof 时,您将看到一个 typeof “对象”。
注意:在您显式地将自定义对象传递给 throw 的情况下,它的行为就像您使用 new 关键字调用构造函数一样,因此,catch 块将返回自定义对象而不是 message 属性价值。例如:throw {name:"RangeError",message:"range is out of scope",environment:"Happened in testing function"}。
总而言之,使用适合您的任何您知道自己在做什么。但是对我来说,如果我不需要太多数据而只需要错误,那么我会选择 Primitive returner。
答案 6 :(得分:2)
除其余答案外,我想展示一下React的一种区别。
如果我抛出一个new Error()
并且处于开发模式,我将得到一个错误屏幕和一个控制台日志。如果我抛出字符串文字,那么如果我不看控制台日志,我只会在控制台中看到它,并且可能会错过它。
将错误记录到控制台 中,并在开发模式下显示错误屏幕(该屏幕在生产中不可见)。
throw new Error("The application could not authenticate.");
以下代码仅登录到控制台:
throw "The application could not authenticate.";
答案 7 :(得分:2)
axios.put('/users/${this.$auth.user().id', fd, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
既可用于对象也可用于字符串。但是,与其他方法相比,它的支持较少。throw something
仅可用于字符串并将对象变成catch块中无用的[Object obj]。 / p>
答案 8 :(得分:1)
TLDR:它们是等效的。
// this:
const x = Error('I was created using a function call!');
// has the same functionality as this:
const y = new Error('I was constructed via the "new" keyword!');
来源:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
答案 9 :(得分:0)
Error
构造函数用于创建错误对象。发生运行时错误时,将引发错误对象。 Error对象也可以用作用户定义的异常的基础对象。
通过throw
语句引发用户定义的错误。程序控制将传递到调用堆栈中的第一个catch
块。
使用和不使用Error对象引发错误之间的区别:
throw {'hehe':'haha'};
在chrome devtools中,外观如下:
Chrome告诉我们,我们有一个未捕获的错误,它只是一个JS对象。对象本身可能具有有关错误的信息,但我们仍然不立即知道它来自何处。当我们处理代码并对其进行调试时,它不是很有用。
throw new Error({'hehe':'haha'});
在chrome devtools中,外观如下:
扩展对象时,使用Error对象引发的错误为我们提供了堆栈跟踪。这为我们提供了有价值的信息,准确地指出了错误的来源,这在调试代码时通常是有价值的信息。还要注意,错误显示为[object Object]
,这是因为Error
构造函数将消息字符串作为第一个参数。当它收到一个对象时,它将把它强制为字符串。
答案 10 :(得分:0)
TLDR
throw new Error('problem')
捕获错误发生地点的许多属性。
throw 'problem'
没有
new Error('message')
捕获执行堆栈 + 其他使用 Error 对象可以让您在抛出错误的地方捕获执行堆栈。因此,当错误向上传递到错误处理树时,此堆栈快照也会传递。
因此在我的代码库中的某处插入 throw "test error"
会导致:
而 throw new Error('test error')
导致:
您可以看到本机 Error 对象在我抛出错误时捕获堆栈,并使其可用于捕获错误的任何对象。这让我在调试时更容易追踪问题。
除此之外,它还捕获诸如 fileName
, lineNumber
and columnNumber
之类的属性。
异常记录器将为您捕获堆栈跟踪
在这种情况下,堆栈会被打印到浏览器控制台中,但如果您使用的是 Appsignal 或 Bugsnag 等 Javascript 错误记录工具,那么该堆栈也将在其中可用。如果您检查错误对象,您可以直接访问堆栈快照:
err = new Error('test')
err.stack
throw 'problem'
如果您抛出的错误是您计划捕获和处理的预期错误,那么您将不会从堆栈快照中获得太多用处。
那么,假设您使用的是 http 服务,它返回一个 500 HTTP 代码。您可以将此视为错误,您可以throw {responseCode=500}
并随后捕获并处理该错误。
new Error('problem')
当您因为应用程序中发生意外或越界而引发错误时,假设本地数据存储已损坏,您可能处于不想处理它的情况,但是你确实想标记它。在这种情况下,现在是使用 Error 对象的好时机,这样您就有了堆栈快照。
通过使用 throw new Error('Datastore is corrupted')
,您可以更轻松地追溯发生的事情。