【问题标题】:Why is my custom exception class type losing context when an instance is thrown?为什么我的自定义异常类类型在抛出实例时会丢失上下文?
【发布时间】:2021-10-23 20:57:15
【问题描述】:

我的对象上下文不是我期望的。

它应该是抛出的类类型,但捕获时是对象。 为什么会这样? 大概是什么傻事。几乎总是如此。

我必须使用旧的未知 JS 运行时。它无法升级,因此我无法使用更新的功能等。

我将代码移植到 Node 中运行,因此在导入和导出方面略有不同,但原型和功能是相同的。行为也一样:不需要。

这个 ClassA 提供了测试用例。

import ClassB from "./ClassB.js"
import ExceptionC from "./ClassB.js"

export default function ClassA() {};

ClassA.prototype = {
    objB: new ClassB(),

    funcA: function() {
        try {
            this.objB.thrower();
        }
        catch (thrownFromB) {
            console.log("Caught Exception. This exception instance should be an ExceptionC. It is type:" + typeof thrownFromB);
            if (thrownFromB instanceof ExceptionC) {
                console.log("ExceptionC message: " + thrownFromB.message + "  origError: " + thrownFromB.origError);
            }
        }
    }
};

这个 ClassB 还提供 throw 和自定义异常类。

export default function ClassB() {};

ClassB.prototype = {
    AugmentedException: function(errorMsg, origError) {
        Error.call(this);
        this.message = errorMsg;
        this.origError = origError;
    },

    ExceptionC: function(errorMsg, origError) {
        AugmentedException.call(this, errorMsg, origError);
    },

    thrower: function() {
        console.log("throwing a new ExceptionC");
        throw new ExceptionC("foo", "bar");
    }
};

这是主要功能。

import ClassA from "./ClassA.js"

var foo = new ClassA();
foo.funcA();

这是输出。

>> OUTPUT:
>> throwing a new ExceptionC...
>> Caught Exception. This exception instance should be an ExceptionC. It is type: object

【问题讨论】:

  • import ExceptionC from "./ClassB.js" - 这不是导入的工作方式。您实际上是在别名 ExceptionC 下导入 ClassB(默认导出)。用console.log(ClassB === ExceptionC)确认。
  • AugmentedExceptionExceptionC 都不应该在任何东西的原型对象上。您也没有正确引用它们。鉴于“失去上下文”的模糊描述,我怀疑你不理解difference between variables and properties?

标签: javascript exception


【解决方案1】:

我可能怀疑的一些问题:

  1. ClassB.js 中,您使用了一些未定义的变量。因此,ReferenceError 被抛出,而不是 ExceptionC。所以在这些行中:

    AugmentedException.call(this, errorMsg, origError);
    // ...
    throw new ExceptionC("foo", "bar");
    

    你可能是这个意思:

    ClassB.prototype.AugmentedException.call(this, errorMsg, origError);
    // ...
    throw new ClassB.prototype.ExceptionC("foo", "bar");
    
  2. ClassA.js 中,您将相同的导出默认类导入到 2 个不同的变量中。因此,在ExceptionC 中,您实际上拥有相同的ClassB。所以在这一行:

    import ExceptionC from "./ClassB.js"
    

    你可能是这个意思:

    const ExceptionC = ClassB.prototype.ExceptionC;
    

有了这些变化,我很期待:

throwing a new ExceptionC
Caught Exception. This exception instance should be an ExceptionC. It is type:object
ExceptionC message: foo  origError: bar

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2020-02-20
  • 2012-09-14
  • 1970-01-01
  • 1970-01-01
  • 2013-02-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多