Remove list of JavaScriptException object properties:
- In Development Mode: always
- In Production Mode: when compiler.stackTrace = emulated
Fixes Issues: 3974
Review at http://gwt-code-reviews.appspot.com/1310802
Review by: scottb@google.com
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9672 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/core/client/JavaScriptException.java b/user/src/com/google/gwt/core/client/JavaScriptException.java
index 495fce7..36efebc 100644
--- a/user/src/com/google/gwt/core/client/JavaScriptException.java
+++ b/user/src/com/google/gwt/core/client/JavaScriptException.java
@@ -74,32 +74,11 @@
}-*/;
private static String getProperties(Object e) {
- return (e instanceof JavaScriptObject)
- ? getProperties0((JavaScriptObject) e) : "";
+ return (GWT.isScript() && e instanceof JavaScriptObject)
+ ? StackTraceCreator.getProperties((JavaScriptObject) e) : "";
}
/**
- * Returns the list of properties of an unexpected JavaScript exception.
- */
- private static native String getProperties0(JavaScriptObject e) /*-{
- var result = "";
- try {
- for (var prop in e) {
- if (prop != "name" && prop != "message" && prop != "toString") {
- try {
- result += "\n " + prop + ": " + e[prop];
- } catch (ignored) {
- // Skip the property if it threw an exception.
- }
- }
- }
- } catch (ignored) {
- // If we can't do "in" on the exception, just return what we have.
- }
- return result;
- }-*/;
-
- /**
* The original description of the JavaScript exception this class wraps,
* initialized as <code>e.message</code>.
*/
diff --git a/user/src/com/google/gwt/core/client/impl/StackTraceCreator.java b/user/src/com/google/gwt/core/client/impl/StackTraceCreator.java
index cee201c..768ef90 100644
--- a/user/src/com/google/gwt/core/client/impl/StackTraceCreator.java
+++ b/user/src/com/google/gwt/core/client/impl/StackTraceCreator.java
@@ -84,6 +84,27 @@
}
/**
+ * Returns the list of properties of an unexpected JavaScript exception.
+ */
+ public native String getProperties(JavaScriptObject e) /*-{
+ var result = "";
+ try {
+ for (var prop in e) {
+ if (prop != "name" && prop != "message" && prop != "toString") {
+ try {
+ result += "\n " + prop + ": " + e[prop];
+ } catch (ignored) {
+ // Skip the property if it threw an exception.
+ }
+ }
+ }
+ } catch (ignored) {
+ // If we can't do "in" on the exception, just return what we have.
+ }
+ return result;
+ }-*/;
+
+ /**
* Attempt to infer the stack from an unknown JavaScriptObject that had been
* thrown. The default implementation just returns an empty array.
*
@@ -162,6 +183,17 @@
t.setStackTrace(stackTrace);
}
+ /**
+ * When compiler.stackMode = emulated, return an empty string, rather than a
+ * list of properties, since the additional information regarding the origin
+ * of the JavaScriptException, relative to compiled JavaScript source code,
+ * adds no real value, since we have fully emulated stack traces.
+ */
+ @Override
+ public String getProperties(JavaScriptObject e) {
+ return "";
+ }
+
@Override
public JsArrayString inferFrom(JavaScriptObject e) {
throw new RuntimeException("Should not reach here");
@@ -390,6 +422,20 @@
}
/**
+ * Returns the list of properties of an unexpected JavaScript exception,
+ * unless compiler.stackMode = emulated, in which case the empty string is
+ * returned. This method should only be called in Production Mode.
+ */
+ public static String getProperties(JavaScriptObject e) {
+ if (!GWT.isScript()) {
+ throw new RuntimeException(
+ "StackTraceCreator should only be called in Production Mode");
+ }
+
+ return GWT.<Collector> create(Collector.class).getProperties(e);
+ }
+
+ /**
* Create a stack trace based on the current execution stack. This method
* should only be called in Production Mode.
*/
diff --git a/user/test/com/google/gwt/core/client/JavaScriptExceptionTest.java b/user/test/com/google/gwt/core/client/JavaScriptExceptionTest.java
index 2c5bd21..cbd8e17 100644
--- a/user/test/com/google/gwt/core/client/JavaScriptExceptionTest.java
+++ b/user/test/com/google/gwt/core/client/JavaScriptExceptionTest.java
@@ -16,6 +16,8 @@
package com.google.gwt.core.client;
import com.google.gwt.junit.client.GWTTestCase;
+import com.google.gwt.junit.client.WithProperties;
+import com.google.gwt.junit.client.WithProperties.Property;
/**
* Any JavaScript exceptions occurring within JSNI methods are wrapped as this
@@ -53,6 +55,35 @@
@com.google.gwt.core.client.JavaScriptExceptionTest::throwJava(Ljava/lang/Throwable;)(t);
}-*/;
+ public void assertJsoProperties(boolean extraPropertiesShouldBePresent) {
+ JavaScriptObject jso = makeJSO();
+ try {
+ throwNative(jso);
+ fail();
+ } catch (JavaScriptException e) {
+ assertEquals("myName", e.getName());
+ assertEquals("myDescription", e.getDescription());
+ assertSame(jso, e.getException());
+ assertTrue(e.getMessage().contains("myName"));
+ assertTrue(e.getMessage().contains("myDescription"));
+ if (extraPropertiesShouldBePresent) {
+ assertTrue(
+ "message does not contain 'extraField', but should: "
+ + e.getMessage(), e.getMessage().contains("extraField"));
+ assertTrue(
+ "message does not contain 'extraData', but should:"
+ + e.getMessage(), e.getMessage().contains("extraData"));
+ } else {
+ assertFalse(
+ "message contains 'extraField', but shouldn't: " + e.getMessage(),
+ e.getMessage().contains("extraField"));
+ assertFalse(
+ "message contains 'extraData', but shouldn't:" + e.getMessage(),
+ e.getMessage().contains("extraData"));
+ }
+ }
+ }
+
/**
* This test doesn't work in Development Mode yet; we'd need a way to throw
* true native objects as exceptions. Windows/IE is the deal killer right now
@@ -82,21 +113,46 @@
assertSame(e, t);
}
}
+
+ @WithProperties({
+ @Property(name = "compiler.stackMode", value = "emulated")
+ })
+ public void testJsoStackModeEmulated() {
+ /**
+ * Whether we're in Development Mode, or in Production Mode with
+ * compiler.stackMode = emulated, extra properties should not be present.
+ *
+ * @see StackTraceCreator#getProperties(JavaScriptObject)
+ */
+ assertJsoProperties(false);
+ }
+
+ @WithProperties({
+ @Property(name = "compiler.stackMode", value = "native")
+ })
+ public void testJsoStackModeNative() {
+ /**
+ * In Production Mode with compiler.stackMode = native, extra properties
+ * should be present. In Development Mode, extra properties should not be
+ * present.
+ *
+ * @see StackTraceCreator#getProperties(JavaScriptObject)
+ */
+ assertJsoProperties(GWT.isScript());
+ }
- public void testJso() {
- JavaScriptObject jso = makeJSO();
- try {
- throwNative(jso);
- fail();
- } catch (JavaScriptException e) {
- assertEquals("myName", e.getName());
- assertEquals("myDescription", e.getDescription());
- assertSame(jso, e.getException());
- assertTrue(e.getMessage().contains("myName"));
- assertTrue(e.getMessage().contains("myDescription"));
- assertTrue(e.getMessage().contains("extraField"));
- assertTrue(e.getMessage().contains("extraData"));
- }
+ @WithProperties({
+ @Property(name = "compiler.stackMode", value = "strip")
+ })
+ public void testJsoStackModeStrip() {
+ /**
+ * In Production Mode with compiler.stackMode = strip, extra properties
+ * should be present. In Development Mode, extra properties should not be
+ * present.
+ *
+ * @see StackTraceCreator#getProperties(JavaScriptObject)
+ */
+ assertJsoProperties(GWT.isScript());
}
public void testNull() {