目前ExceptionInfo以原始构造函数形式实现,继承自js/Error,并添加了一些临时的javascript级别修复以满足deftype功能的一小部分(主要是用于打印)。
不幸的是,这与 cljs-devtools(链接:1)不兼容。当我开始尝试ExceptionInfo和cljs-devtools v0.8(它新支持打印deftype,链接:2)时,这个问题出现了。ExceptionInfo不包含getBasis、cljs$lang$type、cljs$lang$ctorStr等类似的工具。
我提出的补丁实施ExceptionInfo作为真实的deftype,并进行了一些修正以提供向后兼容性。我非常确信我们不应该破坏ExceptionInfo构造函数接受3个参数并在构造函数中动态合成其他字段当前的合同。
实现细节
1) 首先,我们像正常的deftype一样定义ExceptionInfo(以获取模板)
2) 然后在ExceptionInfoTypeTemplate中记住ExceptionInfo的引用
3) 然后用原始构造函数重新定义ExceptionInfo,该函数应模拟原始行为(通过刮取新创建的js/Error实例,但调用ExceptionInfoTypeTemplate以进行正确的deftype初始化)
4) 然后将ExceptionInfoTypeTemplate的键复制到ExceptionInfo中
5) 然后将ExceptionInfo的原型设置为ExceptionInfoTypeTemplate的原型
6) 然后将ExceptionInfo原型的构造函数指向我们的重新定义的构造函数
7) 然后修补ExceptionInfo的原型以继承js/Error(请注意这会覆盖ExceptionInfoTypeTemplate - 但我们不关心它)
这实际上为我们提供了一个良好工作的ExceptionInfo deftype,其中包含重新定义的构造函数,该构造函数包装了类型构造函数以实现向后兼容性。
我们还修补了ExceptionInfo的原型以继承js/Error,方式和原始代码一样。
注意:具有有效deftype,我们可以将IPrintWithWriter和toString实现移动到deftype本身。
(链接:1)https://github.com/binaryage/cljs-devtools/issues/23
(链接:2)https://github.com/binaryage/cljs-devtools/releases/tag/v0.8.0