目前ExceptionInfo作为原始构造函数实现,继承自js/Error并在JavaScript级别进行了一些即兴修补以满足deftype功能的很小一部分(主要是用于打印)。
这与cljs-devtools(link: 1)不兼容。在开始使用ExceptionInfo和最新支持打印deftype的cljs-devtools v0.8(link: 2)时出现了这个问题。ExceptionInfo不包含getBasis、cljs$lang$type、cljs$lang$ctorStr等类似机制。
我提出的补丁实现了ExceptionInfo作为合适的deftype,并进行了一些补丁工作以提供向后兼容。我非常确信我们不应该破坏ExceptionInfo构造函数接受3个参数并在构造函数中动态合成其他字段的当前约定。
实现细节
1) 首先,我们将ExceptionInfo定义为正常的deftype(以获得模板)
2) 然后,我们将ExceptionInfo在ExceptionInfoTypeTemplate中的引用保存在那里
3) 然后,我们使用原始构造函数重新定义ExceptionInfo,该构造函数应该模仿原始行为(通过抓取新创建的js/Error实例,但调用ExceptionInfoTypeTemplate来进行合适的deftype初始化)
4) 然后,我们将ExceptionInfoTypeTemplate中的键复制到ExceptionInfo中
5) 然后,我们将ExceptionInfo的原型设置为ExceptionInfoTypeTemplate的原型
6) 然后,我们将ExceptionInfo原型的构造函数指向我们重新定义的构造函数
7) 然后,我们将ExceptionInfo的原型修补以从js/Error继承(注意这也覆盖了ExceptionInfoTypeTemplate - 但我们不在乎这一点)
这有效地为我们提供了一个具有重新定义的构造函数的正确工作的ExceptionInfo deftype,该构造函数包装了deftype的构造函数以实现向后兼容。
我们还修补ExceptionInfo的原型以按与原始代码相同的方式从js/Error继承。
注意:有了工作deftype,我们可以将IPrintWithWriter和toString实现移动到deftype本身。
(link: 1) https://github.com/binaryage/cljs-devtools/issues/23
(link: 2) https://github.com/binaryage/cljs-devtools/releases/tag/v0.8.0