From bbda91d213a33e47e75ac13158a442d1b17b4e2a Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Wed, 11 Dec 2024 22:18:51 +0100 Subject: [PATCH 1/2] Fix JS to Java exception conversion for UncaughtExceptionHandler --- .../org/gwtproject/core/client/GWTTest.java | 24 +++++++++++++++++++ .../java/org/gwtproject/core/client/GWT.java | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/gwt-core-gwt2-tests/src/test/java/org/gwtproject/core/client/GWTTest.java b/gwt-core-gwt2-tests/src/test/java/org/gwtproject/core/client/GWTTest.java index 7b9a561..ef841ed 100644 --- a/gwt-core-gwt2-tests/src/test/java/org/gwtproject/core/client/GWTTest.java +++ b/gwt-core-gwt2-tests/src/test/java/org/gwtproject/core/client/GWTTest.java @@ -16,8 +16,14 @@ package org.gwtproject.core.client; import com.google.gwt.junit.client.GWTTestCase; +import elemental2.dom.DomGlobal; +import java.util.ArrayList; +import java.util.List; public class GWTTest extends GWTTestCase { + + private List caught = new ArrayList<>(); + @Override public String getModuleName() { return "org.gwtproject.core.Core"; @@ -32,4 +38,22 @@ public void testIsClient() { assertTrue(GWT.isClient()); assertTrue(org.gwtproject.core.shared.GWT.isClient()); } + + public void testReportUncaughtError() { + GWT.setUncaughtExceptionHandler(caught::add); + GWT.reportUncaughtException(new RuntimeException()); + DomGlobal.setTimeout( + (ignore) -> { + assertEquals(1, caught.size()); + assertEquals("java.lang.JsException", caught.get(0).getClass().getName()); + finishTest(); + }, + 1000); + delayTestFinish(3000); + } + + @Override + public boolean catchExceptions() { + return false; + } } diff --git a/gwt-core/src/main/java/org/gwtproject/core/client/GWT.java b/gwt-core/src/main/java/org/gwtproject/core/client/GWT.java index d8fea32..03d7d5d 100644 --- a/gwt-core/src/main/java/org/gwtproject/core/client/GWT.java +++ b/gwt-core/src/main/java/org/gwtproject/core/client/GWT.java @@ -152,7 +152,7 @@ private static void addOnErrorHandler(Window window, Window.OnerrorFn onerrorFn) @JsMethod private static native Throwable fromObject(Object obj) /*-{ //GWT2 impl using JSNI, see GWT.native.js for the j2cl impl - var throwable = @java.lang.Throwable::of(*)(obj); + return @java.lang.Throwable::of(*)(obj); }-*/; @JsType(isNative = true, name = "window", namespace = "") From ec0e3d1d733c19942089d8eb0f78e166511a8557 Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Mon, 2 Dec 2024 18:43:14 +0100 Subject: [PATCH 2/2] Throw JS exception instead of Java wrapping object --- .../org/gwtproject/core/client/GWTTest.java | 2 +- .../java/org/gwtproject/core/client/GWT.java | 19 ++++++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/gwt-core-gwt2-tests/src/test/java/org/gwtproject/core/client/GWTTest.java b/gwt-core-gwt2-tests/src/test/java/org/gwtproject/core/client/GWTTest.java index ef841ed..3d4151e 100644 --- a/gwt-core-gwt2-tests/src/test/java/org/gwtproject/core/client/GWTTest.java +++ b/gwt-core-gwt2-tests/src/test/java/org/gwtproject/core/client/GWTTest.java @@ -45,7 +45,7 @@ public void testReportUncaughtError() { DomGlobal.setTimeout( (ignore) -> { assertEquals(1, caught.size()); - assertEquals("java.lang.JsException", caught.get(0).getClass().getName()); + assertEquals("java.lang.RuntimeException", caught.get(0).getClass().getName()); finishTest(); }, 1000); diff --git a/gwt-core/src/main/java/org/gwtproject/core/client/GWT.java b/gwt-core/src/main/java/org/gwtproject/core/client/GWT.java index 03d7d5d..6ac902a 100644 --- a/gwt-core/src/main/java/org/gwtproject/core/client/GWT.java +++ b/gwt-core/src/main/java/org/gwtproject/core/client/GWT.java @@ -17,6 +17,7 @@ import elemental2.dom.DomGlobal; import elemental2.dom.Window; +import jsinterop.annotations.JsFunction; import jsinterop.annotations.JsMethod; import jsinterop.annotations.JsType; import jsinterop.base.Js; @@ -58,11 +59,10 @@ public static T create(Class clazz) { public static void reportUncaughtException(Throwable e) { // throw an exception "later" so that it ends up handled by the global // error handler. Same code as in GWT2's Impl.reportToBrowser() - DomGlobal.setTimeout( - ignore -> { - throw_(e); - }, - 0); + setTimeout( + () -> { + throw e; + }); } /** @@ -160,8 +160,13 @@ private static class InnerWindow { static Window window; } - @JsMethod(namespace = "", name = "throw") - private static native void throw_(Object object); + @JsFunction + private interface Throwing { + void run() throws Throwable; + } + + @JsMethod(namespace = "", name = "setTimeout") + private static native void setTimeout(Throwing throwingFunction); public static boolean isClient() { return org.gwtproject.core.shared.GWT.isClient();