2024年Clojure状态调查中分享您的想法!

欢迎!请查看关于页面了解有关如何使用本网站的更多信息。

0
编译器

在Clojure 1.9中,如果您抛出一个不是Throwable实例的对象,您会得到以下错误信息

`
user=> (try "something" (catch Object o "oops"))

VerifyError (class: user$eval1432, method: invokeStatic signature: ()Ljava/lang/Object;) catch_type not a subclass of Throwable java.lang.Class.getDeclaredConstructors0 (Class.java:-2)
`

错误信息并不太糟糕:它告诉您大部分您需要知道的信息(除了您尝试捕获的实际类)。

但在不久的将来,Clojure可能会升级到Java 1.8字节码,那时错误将看起来像这样

`
user=> (try "something" (catch Object o "oops"))

VerifyError 在异常处理程序6中捕获类型不是Throwable的子类
异常详细信息
位置

user$eval1444.invokeStatic()Ljava/lang/Object; @6: astore_1

原因

Type 'java/lang/Object' (constant pool 17) is not assignable to 'java/lang/Throwable'

字节码

0000000: 120d 4ba7 000a 4c12 0f4b a700 032a b0

异常处理程序表

bci [0, 3] => handler: 6

栈映射表

same_locals_1_stack_item_frame(@6,Object[#17])
append_frame(@13,Object[#21])

java.lang.Class.getDeclaredConstructors0 (Class.java:-2)
`

对我来说,这似乎是一个内部编译器错误,我认为它不应该向用户展示。

补丁通过在try表达式解析时添加检查点来修复问题,检查您要捕获的东西是否是Throwable的子类。

2 个答案

0

评论由:alexmiller

编译器永远不应该生成包含VerifyError的字节码,因此这绝对是一个错误。

0
参考:https://clojure.atlassian.net/browse/CLJ-2345(由schmee报告)
...