在Groovy SwingBuilder.doOutside中处理异常

在Groovy SwingBuilder.doOutside中处理异常,groovy,swingbuilder,Groovy,Swingbuilder,(这是Groovy 1.8.9。该问题在Groovy 2.1.0-rc-1中得到修复) 我正在尝试处理SwingBuilder.doOutside{}中发生的异常。我使用了Thread.setDefaultUncaughtExceptionHandler(),但它似乎没有拦截doOutside{}中的未捕获异常 下面是一个示例程序,说明了这个问题。如果从命令行运行此命令并单击EDT Exception按钮,我会在stderr上看到printStackTrace()结果。如果单击“外部异常”,则不

(这是Groovy 1.8.9。该问题在Groovy 2.1.0-rc-1中得到修复)

我正在尝试处理
SwingBuilder.doOutside{}
中发生的异常。我使用了
Thread.setDefaultUncaughtExceptionHandler()
,但它似乎没有拦截
doOutside{}
中的未捕获异常

下面是一个示例程序,说明了这个问题。如果从命令行运行此命令并单击EDT Exception按钮,我会在stderr上看到
printStackTrace()
结果。如果单击“外部异常”,则不会显示任何内容。我做错了什么

import groovy.swing.SwingBuilder

class ExceptionTest {
    static main(args) {
        Thread.setDefaultUncaughtExceptionHandler(
            { thread, exception ->
                System.err.println "thread ${thread.getName()}"
                exception.printStackTrace()
            } as Thread.UncaughtExceptionHandler)

        def swing = new SwingBuilder()

        def testEDTButton = swing.button('EDT exception')
        testEDTButton.actionPerformed = { throw new Exception("EDT exception") }

        def testOutsideButton = swing.button('Outside Exception')
        testOutsideButton.actionPerformed = { swing.doOutside { throw new Exception("Exception outside") } }

        def frame = swing.frame(title: 'Test exception reporting') {
            vbox {
                widget(testEDTButton)
                widget(testOutsideButton)
            }
        }
        frame.pack()
        frame.show()
    }
}

我查看了Groovy 1.8.9的SwingBuilder源代码,发现
doOutside
使用
ExecutorService.submit()
,如果它是从EDT线程调用的:

private static final ExecutorService DEFAULT_EXECUTOR_SERVICE = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors())
...
DEFAULT_EXECUTOR_SERVICE.submit(c)
submit()。
Future
捕获其异常,并且仅在调用
Future.get()
时才会抛出异常本身。但在
doOutside()
中,这种情况永远不会发生

因此,我需要在传递给
doOutside()
的闭包中放置一个try-catch,以便能够注意到那里发生了异常

注意:Groovy 2.1.0-rc-1中的
Future
被一个简单的
Thread.start()
替换(请参见bug)。这就消除了异常捕获问题