0

您知道 JavaScript 基本上可以将任何对象甚至原始对象作为异常抛出:

throw 1;
throw { text: "hello" }

可悲的是,像 Firefox 这样的调试器会将异常记录到控制台,包括指向抛出内置Error对象时抛出异常的代码行的链接。

为了解决这个限制,我想:为什么我不重写toString并给出一个异常实例作为Error构造函数的参数,所以异常将被隐式转换为string

var ArgumentException = function(args) {
   this._argName= args.argName;
}

ArgumentException.prototype = {
    _argName: null,

    get argName() { return this._argName; },

    toString: function() { 
       return "ArgumentException was thrown. Affected argument: " + this.argName;
    }
};

throw Error(new ArgumentException({ argName: "someArgument" }));

显然,上面的代码清单是对真实案例的简化。

好的,这有效并解决了整个问题。

但这会破坏使用异常的目的,因为 atry/catch将无法按类型处理异常:

try
{
    throw Error(new ArgumentException({ argName: "someArgument" }));
} catch(e) {
    if(e instanceof ArgumentException) {
         // This will happen never! "e" will hold a Error instance!!!!
    }
}

你怎么解决这个问题?事实上,这是 Web 浏览器调试器的问题,而不是实际 JavaScript 的问题,但由于调试是任何开发周期中的重要点,因此应该认真对待。

先感谢您。

编辑

我想分享我的另一个结论:

try
{
    debugger;
    throw new ArgumentException({ argName: "someArgument" });
} catch(e) {
    if(e instanceof ArgumentException) {

    }
}

上面的解决方案会将异常记录到调试器控制台,但它会在调试器被抛出之前停止它。好的,您没有获得指向确切行的链接,但调试器会停在那里,因此您可以知道将在哪里引发异常。

4

1 回答 1

1

为什么不让你的异常继承自Error呢?

function ArgumentException(data) {
    this.name = "ArgumentException";
    this.message = arguments.length ? 'Affected argument: ' + data.argName : "Illegal argument";
}
// set up inheritance
ArgumentException.prototype = Object.create(Error.prototype);
ArgumentException.prototype.constructor = ArgumentException;

// use it 
try {
    throw new ArgumentException({argName: "someArgument"});
} catch(e) {
    if(e instanceof ArgumentException) {
        console.log(e); // hi there
    }
}
// see it normally
throw new ArgumentException({argName: "someOtherArgument"});
// ArgumentException: Affected argument: someOtherArgument

有关更多信息,请查看MDN上的自定义错误类型

于 2013-11-04T20:39:34.650 回答