目前ExceptionInfo作为原始构造函数实现,继承了js/Error,并使用一些定制的JavaScript修复来解决deftype功能的一小部分(主要是打印)。
不幸的是,这并不与cljs-devtools(link: 1)很好地配合。当我在ExceptionInfo和cljs-devtools v0.8(新支持打印deftype, link: 2)中进行实验时,这个问题出现了。ExceptionInfo不包含getBasis, cljs$lang$type, cljs$lang$ctorStr和类似的机制。
我提出的修复方案是实施ExceptionInfo作为适当的deftype,并提供一些修补工作以实现向后兼容性。我坚信我们不应该破坏ExceptionInfo构造函数接受3个参数并动态合成其他字段当前协议。
实现细节
1) 首先,我们定义ExceptionInfo作为一个正常的deftype(以获得模板)
2) 然后,我们在ExceptionInfoTypeTemplate中记住对ExceptionInfo的引用
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