正确的非字符串 Javascript 异常

发布于 2024-12-29 12:11:29 字数 411 浏览 5 评论 0原文

不知怎的,这感觉不像是 50 年编程语言发展的顶峰:

  throw "My exception message here";

在 Javascript 中处理异常的正确方法是什么,以便

  • 它们可以被识别(instanceof)

  • < p>除了默认消息和堆栈跟踪之外,它们还可以携带其他有效负载

  • 它们“子类化”基本异常,以便调试控制台等可以提取有意义的信息关于异常

  • 可能的嵌套异常(将异常转换为另一个异常):如果您需要捕获异常并重新抛出新的异常,原始堆栈跟踪将被保留,并且可以通过调试工具进行有意义的读取

  • 他们遵循 Javascript 最佳实践

Somehow this does not feel like the culmination of the 50 years programming language development:

  throw "My exception message here";

What's the correct way to do exceptions in Javascript, so that

  • They can be identified (instanceof)

  • They can carry other payload besides the default message and stack trace

  • They "subclass" base Exception, so that debug console and such can extract meaningful information about the exception

  • Possible nested exceptions (converting exception to another): if you need to catch an exception and rethrow new one the orignal stack trace would be preserved and could be meaningfully read by debugging tools

  • They follow Javascript best practices

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

挽清梦 2025-01-05 12:11:29

throw new Error("message");

或者如果您想更具体,请使用 错误对象

确保抛出真正的错误非常重要,因为它们包含堆栈跟踪。抛出一个字符串是愚蠢的,因为它没有附加任何元数据。

您还可以对错误进行子类化

// for some sensible implementation of extend 
// https://gist.github.com/1441105#file_1pd.js
var MyError = extend(Object.create(Error.prototype), {
   ...
});

throw new Error("message");

or if you want to be more specific use one of the Error Objects

It's important to make sure you throw real errors because they contain the stack trace. Throwing a string is stupid because it doesn't have any meta data attached to it.

You can also subclass errors

// for some sensible implementation of extend 
// https://gist.github.com/1441105#file_1pd.js
var MyError = extend(Object.create(Error.prototype), {
   ...
});
维持三分热 2025-01-05 12:11:29

JavaScript 中的基本“异常”是内置的 Error 对象:

throw new Error("My exception message here");

您可以将自定义异常定义为:

function CustomError(message) {
  this.message = message;
}

CustomError.prototype = new Error();
CustomError.prototype.constructor = CustomError;

使用 instanceof 检查异常类型。还有一个内置异常的便捷列表

A base "exception" in JavaScript is built-in Error object:

throw new Error("My exception message here");

You can define your custom exceptions as:

function CustomError(message) {
  this.message = message;
}

CustomError.prototype = new Error();
CustomError.prototype.constructor = CustomError;

Check for exception type with instanceof. There is also a handy list of built-in exceptions.

贪恋 2025-01-05 12:11:29

你做不到,满足题目要求。

为什么?

问题是获取堆栈。本机错误对象(从现在起为 NativeError),在调用其构造函数时初始化堆栈。要获取 MyError(您的错误子类)中的堆栈,您必须在 MyError 的构造函数内调用 NativeConstructor。因此,您的 MyError 类看起来像这样:

function MyError(msg) {
    Error.call(this, msg);
}

但是,这不起作用。因为根据 HTML5 规范:

“如果您将 Error 作为函数调用,它将返回一个新的 Error目的”。

Error 的构造函数并没有很好地初始化您的自定义错误类,而是创建了一个您没有用处的错误对象。我还没有找到一种方法来调用 NativeError 构造函数并让它初始化 MyError 子类。

并非一切都丢失了。

如果我们放松原来的问题要求,忘记“instanceof”来测试异常类(无论如何Java),而使用“name”来代替,这是可以做到的。只需将 MyError 声明为:

function MyError(msg, customArg) {
    var e = new Error(msg);
    e.name = "MyError";
    e.custom = customArg;
    return e;
}

这就是我所做的。不要打开“instanceof”,而是打开“name”。

You can't do it, and satisfy the question requirements.

Why?

The problem is getting the stack. Native error object (NativeError from now on), initializes the stack when its constructor is called. To get the stack in MyError (your error subclass), you have to call the NativeConstructor inside MyError's constructor. So, your MyError class looks something like this:

function MyError(msg) {
    Error.call(this, msg);
}

But, this does not work. Because according to HTML5 spec:

"if you call Error as a function, it returns a new Error object".

Instead of Error's constructor being nice and initializing your custom error class, it creates an error object that you have no use for. I haven't found a way to call NativeError constructor and have it initialize MyError subclass.

Not all is lost.

If we relax the original question requirements, and forget about "instanceof" to test exception class (so Java anyway), and use "name" instead, it can be done. Just declare MyError as:

function MyError(msg, customArg) {
    var e = new Error(msg);
    e.name = "MyError";
    e.custom = customArg;
    return e;
}

This is what I do. Instead of switching on "instanceof", switch on "name" instead.

葵雨 2025-01-05 12:11:29

您可以通过调用 创建 Error 对象错误构造函数
错误对象可以有消息和名称。捕获时,您可以检查特定名称,也可以通过继承 Error 原型来创建自定义错误类型。这允许使用 instanceof 来区分不同的错误类型。

// Create a new object, that prototypally inherits from the Error constructor.  
function MyError(message) {  
    this.message = message || "Default Message";  
}  
MyError.prototype = new Error();  
MyError.prototype.constructor = MyError;  

try {  
    throw new MyError();  
} catch (e) {  
    console.log(e.name);     // "MyError"  
    console.log(e.message);  // "Default Message"  
}  

try {  
    throw new MyError("custom message");  
} catch (e) {  
    console.log(e.name);     // "MyError"  
    console.log(e.message);  // "custom message"  
}  

示例取自: https://developer.mozilla.org/en/JavaScript/Reference /Global_Objects/错误

You can create an Error object by calling the Error constructor.
An error object can have a message and a name. When catching you can check for a specific name or you can create a custom Error Type by inheriting the Error prototype. This allows the use of instanceof to differ between different Error types.

// Create a new object, that prototypally inherits from the Error constructor.  
function MyError(message) {  
    this.message = message || "Default Message";  
}  
MyError.prototype = new Error();  
MyError.prototype.constructor = MyError;  

try {  
    throw new MyError();  
} catch (e) {  
    console.log(e.name);     // "MyError"  
    console.log(e.message);  // "Default Message"  
}  

try {  
    throw new MyError("custom message");  
} catch (e) {  
    console.log(e.name);     // "MyError"  
    console.log(e.message);  // "custom message"  
}  

Example taken from: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文