处理我的代码上没有发生的异常,我该怎么办?

pup*_*eno 6 java javafx

我有一个JavaFX应用程序,它获取节点的屏幕截图/快照.截取屏幕截图的代码如下所示:

WritableImage image = webView.snapshot(null, null);
Run Code Online (Sandbox Code Playgroud)

这里webView是一个javafx.scene.web.WebView.通常这样可以正常工作,但是当WebView它太大时(我的意思是,大约10240x5548像素),那么,我得到这个例外:

java.lang.NullPointerException
    at com.sun.prism.impl.ps.BaseShaderContext.initLCDBuffer(BaseShaderContext.java:703)
    at com.sun.prism.impl.ps.BaseShaderContext.validateLCDBuffer(BaseShaderContext.java:725)
    at com.sun.prism.impl.ps.BaseShaderGraphics.initLCDSampleRT(BaseShaderGraphics.java:1925)
    at com.sun.prism.impl.ps.BaseShaderGraphics.drawString(BaseShaderGraphics.java:2056)
    at com.sun.javafx.webkit.prism.WCGraphicsPrismContext$10.doPaint(WCGraphicsPrismContext.java:936)
    at com.sun.javafx.webkit.prism.WCGraphicsPrismContext$Composite.paint(WCGraphicsPrismContext.java:1500)
    at com.sun.javafx.webkit.prism.WCGraphicsPrismContext$Composite.paint(WCGraphicsPrismContext.java:1485)
    at com.sun.javafx.webkit.prism.WCGraphicsPrismContext.drawString(WCGraphicsPrismContext.java:948)
    at com.sun.webkit.graphics.GraphicsDecoder.decode(GraphicsDecoder.java:299)
    at com.sun.webkit.graphics.WCRenderQueue.decode(WCRenderQueue.java:92)
    at com.sun.webkit.WebPage.paint2GC(WebPage.java:734)
    at com.sun.webkit.WebPage.paint(WebPage.java:701)
    at com.sun.javafx.sg.prism.web.NGWebView.renderContent(NGWebView.java:96)
    at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
    at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
    at com.sun.javafx.tk.quantum.QuantumToolkit$5.draw(QuantumToolkit.java:1393)
    at com.sun.javafx.tk.quantum.QuantumToolkit$5.run(QuantumToolkit.java:1429)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
    at com.sun.javafx.tk.RenderJob.run(RenderJob.java:58)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:125)
    at java.lang.Thread.run(Thread.java:748)
Run Code Online (Sandbox Code Playgroud)

这不常见,但即使只是告诉用户不支持这样的解决方案,我仍然想处理这种情况.问题是堆栈跟踪根本不会触及我的代码.我的代码中没有一行.我猜这是一个由我调用的东西触发的线程,它会立即返回,然后在线程崩溃时返回.

我的应用程序已经是多线程的,因此,我有一个通用的错误处理程序,如下所示:

public class ErrorHandler implements Thread.UncaughtExceptionHandler {
    public ErrorHandler(String appName) {
        super();
        // init stuff.
    }

    @Override
    public void uncaughtException(Thread t, Throwable e) {
        // Oh my! something went wrong.
        e.printStackTrace(); // We still want to see the exception, specially while developing.
    }
}
Run Code Online (Sandbox Code Playgroud)

我的应用程序启动后立即设置如下:

ErrorHandler errorHandler = new ErrorHandler(APP_NAME);
Thread.setDefaultUncaughtExceptionHandler(errorHandler);
Run Code Online (Sandbox Code Playgroud)

这往往起作用,但由于某种原因,它不适用于该线程.

任何想法我怎样才能抓住情况来做些什么呢?

注意:我发布了一个相关的问题,其中我实际上从生产中获得了异常报告,看起来像一个大截图,但我无法触发该异常,而是触发了这个异常.这个问题在这里:如何解决无法识别的图像加载器:JavaFX中的null?

更加努力地弄清楚发生了什么,最终我得到了stderr:

Outstanding resource locks detected:
D3D Vram Pool: 402,867,712 used (75.0%), 500,823,400 target (93.3%), 536,870,912 max
21 total resources being managed
average resource age is 37.2 frames
0 resources at maximum supported age (0.0%)
11 resources marked permanent (52.4%)
5 resources have had mismatched locks (23.8%)
5 resources locked (23.8%)
12 resources contain interesting data (57.1%)
0 resources disappeared (0.0%)
Run Code Online (Sandbox Code Playgroud)

我不确定那里发生了什么,但它可能是相关的.

小智 1

您可以在执行快照之前引入简单的验证。

if (webView.getHeight() > 1000 || webView.getWidth() > 1000){
    throw new Exception("Web view dimension too big for capturing a snapshot!");
}
WritableImage writImage = webView.snapshot(null, null);
Run Code Online (Sandbox Code Playgroud)

如果您不想对 webView 可以拥有的最大值进行硬编码,您只需获取当前屏幕边界并与它们进行比较即可。

Rectangle2D primaryScreenBounds = Screen.getPrimary().getVisualBounds();
if (webView.getHeight() > primaryScreenBounds.getHeight() || webView.getWidth() > primaryScreenBounds.getWidth()){
    throw new Exception("Webview exceeds screen dimensions!");
}
Run Code Online (Sandbox Code Playgroud)