使用 JavaScript 手动/人为抛出 DOMException

问题描述 投票:0回答:3

是否可以在纯 JavaScript 中手动抛出 DOMException 错误? 我读过的文档表明它应该相对容易构建(至少在Java中)

但是,在 Chrome 中,以下代码会返回

TypeError: Illegal constructor
:

// DOM SYNTAX_ERR (12)
var myDOMException = new DOMException(12,"I'm sorry Dave, I'm afraid I can't do that.");

遗憾的是,这是我在阅读W3 文档后所期望的,它似乎根本没有指定构造函数。 (顺便说一句,虽然我对 IDL 并不是特别“熟悉”,但我会假设它们的变体将支持构造函数的规范。)

令人沮丧的是,DOMException 类诱人地潜伏在全局范围内。我该如何使用它? 我可以使用它吗?

更新

自从我写这篇文章以来,我有了一些发现 - 即:

var myDOMException = DOMException.constructor(12,"Error Message"); var myDOMException2 = DOMException.constructor.call(DOMException,DOMException.SYNTAX_ERR,"Error Message");

看起来成功了!

...没那么快。

$> myDOMException instanceof DOMException false $> myDOMException2 instanceof DOMException false

可能更令人反感:

$> myDOMException.constructor function Number() { [native code] }

一如既往,任何帮助将不胜感激。

更新#2

只是为了澄清我返回 DOMException 对象而不是更通用的错误的原因 - 我正在尝试在纯 JavaScript 中实现

WHATWG 的定时文本跟踪规范。在许多情况下,需要正确的解决方案来返回 DOMException 对象,特别是代码为 12 (SYNTAX_ERR) 的情况

javascript dom
3个回答
12
投票
至少在 Firefox 中,

DOMException

 不是一个函数。它是定义了几个常量的“一个对象”。 
typeof DOMException === 'object' // true (not 'function')

可以这样使用:

try { throw DOMException; } catch(e) { if (e === DOMException) console.log("caught DOMException") }

如果您尝试发出
DOMException
信号但不需要

DOMException

 的实际实例,则此方法有效。
丑陋的黑客(基本上有效)

如果您绝对需要一个具有

DOMException

代码的

SYNTAX_ERR

 实例,您可以执行一项操作来创建一个实例,然后 
throw
function createSyntaxException() {
    try {
        // will cause a DOMException
        document.querySelectorAll("div:foo");
    } catch(e) {
        return e;
    }
}

throw createSyntaxException();

当然,抛出的异常的详细信息与您的具体情况不符,但生成的对象将具有正确的代码并通过
instanceof
检查。

var e = createSyntaxException();
console.log(e instanceof DOMException); // true
console.log(e.code === e.SYNTAX_ERR); // true

您可以通过子类化
DOMException
并为其每个(只读)属性添加 getter/setter 来缓解细节问题。

function DOMExceptionCustom() {
    var message;
    this.__defineGetter__("message", function(){
        return message;
    });
    this.__defineSetter__("message", function(val){
        message = val;
    });
}

// subclass DOMException
DOMExceptionCustom.prototype = createSyntaxException();

var err = new DOMExceptionCustom();
err.message = "my custom message";

生成的对象具有所需的属性:

console.log(err.code === err.SYNTAX_ERR); // true console.log(err.message); // "my custom message" console.log(err instanceof DOMExceptionCustom); // true console.log(err instanceof DOMException); // true

这是我的破解方法。基于 ECMAScript 5 和 WebIDL 的解决方案。
我已经与致力于 WebIDL 的 W3C/ECMAScript 加入工作组

1
投票

function CustomDOMException(code, message) { //throw on missing code if (typeof code !== "number") { throw TypeError("Wrong argument"); } //we need the codes, to get the "name" property. var consts = { 1: "INDEX_SIZE_ERR", 3: "HIERARCHY_REQUEST_ERR", 4: "WRONG_DOCUMENT_ERR", 5: "INVALID_CHARACTER_ERR", 7: "NO_MODIFICATION_ALLOWED_ERR", 8: "NOT_FOUND_ERR", 9: "NOT_SUPPORTED_ERR", 11: "INVALID_STATE_ERR", 12: "SYNTAX_ERR", 13: "INVALID_MODIFICATION_ERR", 14: "NAMESPACE_ERR", 15: "INVALID_ACCESS_ERR", 17: "TYPE_MISMATCH_ERR", 18: "SECURITY_ERR", 19: "NETWORK_ERR", 20: "ABORT_ERR", 21: "URL_MISMATCH_ERR", 22: "QUOTA_EXCEEDED_ERR", 23: "TIMEOUT_ERR", 24: "INVALID_NODE_TYPE_ERR", 25: "DATA_CLONE_ERR" } if ((code in consts) === false) { throw TypeError("Unknown exception code: " + code); } //props for adding properties var props = {}; //generate an exception object var newException; try { //force an exception to be generated; document.removeChild({}) } catch (e) { //use it as the prototype newException = Object.create(Object.getPrototypeOf(e)); } //get the name of the exception type var name = consts[code]; //add the properties var props = {value: null, writable: true, enumerable: false, Configurable: true}; //name props.value = name; Object.defineProperty(newException, "name", props); props.value = code; Object.defineProperty(newException, "code", props); props.value = message; Object.defineProperty(newException, "message", props); //Make sure it "stringifies" properly var finalMessage; var obj = this; if (typeof message === "function") { finalMessage = function() { return message.call(newException) } } else { finalMessage = function() { return name + ": DOM Exception " + code; } } props.value = function() { return finalMessage.call(newException) } Object.defineProperty(newException, "toString", props); return newException; } 还有一些测试:

// Throws SYNTAX_ERR    
console.log(new CustomDOMException(12)); 

// Custom message 
console.log(new CustomDOMException(1, "ERROR!")); 

// Custom message 
console.log(new CustomDOMException(1, function() {
    return "Custom Err:" + this.name + " : " + Date.now()
}));

// Throws TypeError     
try {
    new CustomDOMException(2)
} catch (e) {
    console.log(e);    
}

// Throws TypeError
try {
    new CustomDOMException()
} catch (e) {
    console.log(e);    
}    

// Throws TypeError    
try {
    new CustomDOMException("Wee!")
} catch (e) {
    console.log(e);    
}

//Check the inheritance chain     
var ext = new CustomDOMException(17);
var isInstance = ext instanceof DOMException;
console.log("instanceof DOMException: " + isInstance)​

虽然这是一个老问题,

0
投票

error.code

有意义,但不能用于错误构造。
  • error.code
    将自动匹配
  • error.name
  • ,例如
    TimeoutError
    AbortError
    TypeError
    
    
    当您想要错误显示 
    error.code = DOMException.SYNTAX_ERR (12)
  • 时,您可以使用
document.querySelector('a::b')

创建该错误并找出其错误名称。


那么你就可以拥有

imgthrow new DOMException("I'm sorry Dave, I'm afraid I can't do that.", "SyntaxError")

您还可以将 

DOMExceptionimg 更改为

MyOwnError

    class MyOwnError extends DOMException{
        constructor(msg){
            super(msg, 'SyntaxError');
        }
    }
throw new MyOwnError("I'm sorry Dave, I'm afraid I can't do that.", "SyntaxError")

img

img

class MyOwnError extends DOMException { constructor(msg) { super(msg, 'SyntaxError'); } } const err = new MyOwnError("Oops...") console.log(err.code === err.SYNTAX_ERR); // true console.log(err.message); // "my custom message" console.log(err instanceof MyOwnError); // true console.log(err instanceof DOMException); // true throw err


    

© www.soinside.com 2019 - 2024. All rights reserved.