Issue ROO-954: Support for transmitting stack traces for sever exceptions.
Review at http://gwt-code-reviews.appspot.com/886801
Review by: amitmanjhi@google.com
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@8808 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/AbstractRequest.java b/user/src/com/google/gwt/requestfactory/client/impl/AbstractRequest.java
index d9e3b79..90e781f 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/AbstractRequest.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/AbstractRequest.java
@@ -102,7 +102,9 @@
public void handleResponseText(String responseText) {
JsonResults results = JsonResults.fromResults(responseText);
if (results.getException() != null) {
- receiver.onFailure(new ServerFailure(results.getException()));
+ ServerFailureRecord cause = results.getException();
+ receiver.onFailure(new ServerFailure(
+ cause.getMessage(), cause.getType(), cause.getTrace()));
return;
}
processRelated(results.getRelated());
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/JsonResults.java b/user/src/com/google/gwt/requestfactory/client/impl/JsonResults.java
index 74be2c5..a39db1e 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/JsonResults.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/JsonResults.java
@@ -32,7 +32,7 @@
protected JsonResults() {
}
- public final native String getException() /*-{
+ public final native ServerFailureRecord getException() /*-{
return this.exception || null;
}-*/;
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/ServerFailureRecord.java b/user/src/com/google/gwt/requestfactory/client/impl/ServerFailureRecord.java
new file mode 100644
index 0000000..1042c35
--- /dev/null
+++ b/user/src/com/google/gwt/requestfactory/client/impl/ServerFailureRecord.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.requestfactory.client.impl;
+
+import com.google.gwt.core.client.JavaScriptObject;
+
+/**
+ * Contains details of a server error.
+ */
+public final class ServerFailureRecord extends JavaScriptObject {
+
+ protected ServerFailureRecord() {
+ }
+
+ public native String getMessage() /*-{
+ return this.message || "";
+ }-*/;
+
+ public native String getTrace() /*-{
+ return this.trace || "";
+ }-*/;
+
+ public native String getType() /*-{
+ return this.type || "";
+ }-*/;
+}
diff --git a/user/src/com/google/gwt/requestfactory/server/DefaultExceptionHandler.java b/user/src/com/google/gwt/requestfactory/server/DefaultExceptionHandler.java
new file mode 100644
index 0000000..344b622
--- /dev/null
+++ b/user/src/com/google/gwt/requestfactory/server/DefaultExceptionHandler.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.requestfactory.server;
+
+import com.google.gwt.requestfactory.shared.ServerFailure;
+
+/**
+ * Default implementation for handling exceptions thrown while
+ * processing a request. Suppresses stack traces and the exception
+ * class name.
+ */
+public class DefaultExceptionHandler implements ExceptionHandler {
+ public ServerFailure createServerFailure(Throwable throwable) {
+ return new ServerFailure("Server Error: " + throwable.getMessage(), null,
+ null);
+ }
+}
\ No newline at end of file
diff --git a/user/src/com/google/gwt/requestfactory/server/ExceptionHandler.java b/user/src/com/google/gwt/requestfactory/server/ExceptionHandler.java
new file mode 100644
index 0000000..9225a95
--- /dev/null
+++ b/user/src/com/google/gwt/requestfactory/server/ExceptionHandler.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.requestfactory.server;
+
+import com.google.gwt.requestfactory.shared.ServerFailure;
+
+/**
+ * Handles an exception produced while processing a request.
+ */
+public interface ExceptionHandler {
+ /**
+ * Generates a {@link ServerFailure} based on the information
+ * contained in the received {@code exception}.
+ *
+ * @see DefaultExceptionHandler
+ */
+ ServerFailure createServerFailure(Throwable throwable);
+}
diff --git a/user/src/com/google/gwt/requestfactory/server/JsonRequestProcessor.java b/user/src/com/google/gwt/requestfactory/server/JsonRequestProcessor.java
index 5d1e767..30d5e6c 100644
--- a/user/src/com/google/gwt/requestfactory/server/JsonRequestProcessor.java
+++ b/user/src/com/google/gwt/requestfactory/server/JsonRequestProcessor.java
@@ -18,6 +18,7 @@
import com.google.gwt.requestfactory.shared.EntityProxy;
import com.google.gwt.requestfactory.shared.EntityProxyId;
import com.google.gwt.requestfactory.shared.ProxyFor;
+import com.google.gwt.requestfactory.shared.ServerFailure;
import com.google.gwt.requestfactory.shared.WriteOperation;
import com.google.gwt.requestfactory.shared.impl.Property;
import com.google.gwt.requestfactory.shared.impl.RequestData;
@@ -131,6 +132,8 @@
private OperationRegistry operationRegistry;
+ private ExceptionHandler exceptionHandler;
+
/*
* <li>Request comes in. Construct the involvedKeys, dvsDataMap and
* beforeDataMap, using DVS and parameters.
@@ -166,13 +169,12 @@
Logger.getLogger(this.getClass().getName()).finest("Outgoing response "
+ response);
return response;
+ } catch (InvocationTargetException e) {
+ JSONObject exceptionResponse = buildExceptionResponse(e.getCause());
+ throw new RequestProcessingException("Unexpected exception", e,
+ exceptionResponse.toString());
} catch (Exception e) {
- JSONObject exceptionResponse = new JSONObject();
- try {
- exceptionResponse.put("exception", "Server error");
- } catch (JSONException jsonException) {
- throw new IllegalStateException(jsonException);
- }
+ JSONObject exceptionResponse = buildExceptionResponse(e);
throw new RequestProcessingException("Unexpected exception", e,
exceptionResponse.toString());
}
@@ -759,6 +761,10 @@
return envelop;
}
+ public void setExceptionHandler(ExceptionHandler exceptionHandler) {
+ this.exceptionHandler = exceptionHandler;
+ }
+
public void setOperationRegistry(OperationRegistry operationRegistry) {
this.operationRegistry = operationRegistry;
}
@@ -819,6 +825,32 @@
propertyContext));
}
+ private JSONObject buildExceptionResponse(Throwable throwable) {
+ JSONObject exceptionResponse = new JSONObject();
+ ServerFailure failure = exceptionHandler.createServerFailure(throwable);
+ try {
+ JSONObject exceptionMessage = new JSONObject();
+
+ String message = failure.getMessage();
+ String exceptionType = failure.getExceptionType();
+ String stackTraceString = failure.getStackTraceString();
+
+ if (message != null && message.length() != 0) {
+ exceptionMessage.put("message", message);
+ }
+ if (exceptionType != null && exceptionType.length() != 0) {
+ exceptionMessage.put("type", exceptionType);
+ }
+ if (stackTraceString != null && stackTraceString.length() != 0) {
+ exceptionMessage.put("trace", stackTraceString);
+ }
+ exceptionResponse.put("exception", exceptionMessage);
+ } catch (JSONException jsonException) {
+ throw new IllegalStateException(jsonException);
+ }
+ return exceptionResponse;
+ }
+
@SuppressWarnings("unchecked")
private Class<? extends EntityProxy> castToRecordClass(Class<?> propertyType) {
return (Class<? extends EntityProxy>) propertyType;
diff --git a/user/src/com/google/gwt/requestfactory/server/RequestFactoryServlet.java b/user/src/com/google/gwt/requestfactory/server/RequestFactoryServlet.java
index f3592f6..eef67b8 100644
--- a/user/src/com/google/gwt/requestfactory/server/RequestFactoryServlet.java
+++ b/user/src/com/google/gwt/requestfactory/server/RequestFactoryServlet.java
@@ -75,6 +75,20 @@
return perThreadResponse.get();
}
+ private final ExceptionHandler exceptionHandler;
+
+ public RequestFactoryServlet() {
+ this(new DefaultExceptionHandler());
+ }
+
+ /**
+ * Use this constructor in subclasses to provide a custom
+ * {@link ExceptionHandler}.
+ */
+ public RequestFactoryServlet(ExceptionHandler exceptionHandler) {
+ this.exceptionHandler = exceptionHandler;
+ }
+
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
@@ -102,6 +116,7 @@
RequestProcessor<String> requestProcessor = new JsonRequestProcessor();
requestProcessor.setOperationRegistry(new ReflectionBasedOperationRegistry(
new DefaultSecurityProvider()));
+ requestProcessor.setExceptionHandler(exceptionHandler);
response.setHeader("Content-Type",
RequestFactory.JSON_CONTENT_TYPE_UTF8);
writer.print(requestProcessor.decodeAndInvokeRequest(jsonRequestString));
diff --git a/user/src/com/google/gwt/requestfactory/server/RequestProcessor.java b/user/src/com/google/gwt/requestfactory/server/RequestProcessor.java
index d408f15..93dd64e 100644
--- a/user/src/com/google/gwt/requestfactory/server/RequestProcessor.java
+++ b/user/src/com/google/gwt/requestfactory/server/RequestProcessor.java
@@ -28,6 +28,15 @@
T decodeAndInvokeRequest(T encodedRequest) throws RequestProcessingException;
/**
+ * Sets the ExceptionHandler to use to convert exceptions caused by
+ * method invocations into failure messages sent back to the client.
+ *
+ * @param exceptionHandler an implementation, such as
+ * {@code DefaultExceptionHandler}
+ */
+ void setExceptionHandler(ExceptionHandler exceptionHandler);
+
+ /**
* Sets the OperationRegistry to be used for looking up invocation metadata.
*
* @param registry an implementation, such as
diff --git a/user/src/com/google/gwt/requestfactory/shared/Receiver.java b/user/src/com/google/gwt/requestfactory/shared/Receiver.java
index 3f1ad48..957d49c 100644
--- a/user/src/com/google/gwt/requestfactory/shared/Receiver.java
+++ b/user/src/com/google/gwt/requestfactory/shared/Receiver.java
@@ -33,7 +33,13 @@
* RuntimeException with the provided error message.
*/
public void onFailure(ServerFailure error) {
- throw new RuntimeException(error.getMessage());
+ String exceptionType = error.getExceptionType();
+ String message = error.getMessage();
+ throw new RuntimeException(exceptionType
+ + ((exceptionType.length() != 0 && message.length() != 0) ? ": " : "")
+ + error.getMessage()
+ + ((exceptionType.length() != 0 || message.length() != 0) ? ": " : "")
+ + error.getStackTraceString());
}
/**
@@ -43,13 +49,14 @@
/**
* Called if an object sent to the server could not be validated. The default
- * implementation calls {@link #onFailure()} if <code>errors</code> is not
- * empty.
+ * implementation calls {@link #onFailure(ServerFailure)} if <code>errors
+ * </code> is not empty.
*/
public void onViolation(Set<Violation> errors) {
if (!errors.isEmpty()) {
onFailure(new ServerFailure(
- "The call failed on the server due to a ConstraintViolation"));
+ "The call failed on the server due to a ConstraintViolation",
+ "", ""));
}
}
}
diff --git a/user/src/com/google/gwt/requestfactory/shared/ServerFailure.java b/user/src/com/google/gwt/requestfactory/shared/ServerFailure.java
index 67eef63..3175f30 100644
--- a/user/src/com/google/gwt/requestfactory/shared/ServerFailure.java
+++ b/user/src/com/google/gwt/requestfactory/shared/ServerFailure.java
@@ -20,19 +20,32 @@
*/
public class ServerFailure {
private final String message;
+ private final String stackTraceString;
+ private final String exceptionType;
/**
* Constructs a ServerFailure with a null message.
*/
public ServerFailure() {
- this(null);
+ this(null, null, null);
}
- public ServerFailure(String message) {
+ public ServerFailure(String message, String exceptionType,
+ String stackTraceString) {
this.message = message;
+ this.exceptionType = exceptionType;
+ this.stackTraceString = stackTraceString;
+ }
+
+ public String getExceptionType() {
+ return exceptionType;
}
public String getMessage() {
return message;
}
+
+ public String getStackTraceString() {
+ return stackTraceString;
+ }
}
diff --git a/user/test/com/google/gwt/requestfactory/RequestFactoryExceptionHandlerTest.gwt.xml b/user/test/com/google/gwt/requestfactory/RequestFactoryExceptionHandlerTest.gwt.xml
new file mode 100644
index 0000000..39c7db2
--- /dev/null
+++ b/user/test/com/google/gwt/requestfactory/RequestFactoryExceptionHandlerTest.gwt.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.0.1//EN" "http://google-web-toolkit.googlecode.com/svn/tags/2.0.1/distro-source/core/src/gwt-module.dtd">
+<!--
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ use this file except in compliance with the License. You may obtain a copy of
+ the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ License for the specific language governing permissions and limitations under
+ the License.
+-->
+<module>
+ <inherits name='com.google.gwt.requestfactory.RequestFactory'/>
+ <!-- use this old inefficient JSON library just for the time being, replace soon -->
+ <inherits name='com.google.gwt.junit.JUnit'/>
+ <inherits name='com.google.gwt.json.JSON'/>
+ <servlet path='/gwtRequest'
+ class='com.google.gwt.requestfactory.server.RequestFactoryExceptionHandlerServlet' />
+</module>
diff --git a/user/test/com/google/gwt/requestfactory/RequestFactorySuite.java b/user/test/com/google/gwt/requestfactory/RequestFactorySuite.java
index 124550f..c04d1f4 100644
--- a/user/test/com/google/gwt/requestfactory/RequestFactorySuite.java
+++ b/user/test/com/google/gwt/requestfactory/RequestFactorySuite.java
@@ -18,6 +18,7 @@
import com.google.gwt.junit.tools.GWTTestSuite;
import com.google.gwt.requestfactory.client.EditorTest;
import com.google.gwt.requestfactory.client.FindServiceTest;
+import com.google.gwt.requestfactory.client.RequestFactoryExceptionHandlerTest;
import com.google.gwt.requestfactory.client.RequestFactoryTest;
import com.google.gwt.requestfactory.client.impl.DeltaValueStoreJsonImplTest;
import com.google.gwt.requestfactory.client.impl.ProxyJsoImplTest;
@@ -37,6 +38,7 @@
suite.addTestSuite(ValueStoreJsonImplTest.class);
suite.addTestSuite(DeltaValueStoreJsonImplTest.class);
suite.addTestSuite(RequestFactoryTest.class);
+ suite.addTestSuite(RequestFactoryExceptionHandlerTest.class);
suite.addTestSuite(FindServiceTest.class);
return suite;
}
diff --git a/user/test/com/google/gwt/requestfactory/client/RequestFactoryExceptionHandlerTest.java b/user/test/com/google/gwt/requestfactory/client/RequestFactoryExceptionHandlerTest.java
new file mode 100644
index 0000000..e3ba01e
--- /dev/null
+++ b/user/test/com/google/gwt/requestfactory/client/RequestFactoryExceptionHandlerTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.requestfactory.client;
+
+import com.google.gwt.requestfactory.shared.Receiver;
+import com.google.gwt.requestfactory.shared.RequestObject;
+import com.google.gwt.requestfactory.shared.ServerFailure;
+import com.google.gwt.requestfactory.shared.SimpleFooProxy;
+import com.google.gwt.requestfactory.shared.SyncResult;
+import com.google.gwt.requestfactory.shared.Violation;
+
+import java.util.Set;
+
+/**
+ * Tests that {@code RequestFactoryServlet} when using a custom
+ * ExceptionHandler.
+ */
+public class RequestFactoryExceptionHandlerTest extends RequestFactoryTest {
+
+ @Override
+ public String getModuleName() {
+ return "com.google.gwt.requestfactory.RequestFactoryExceptionHandlerTest";
+ }
+
+ @Override
+ public void testServerFailure() {
+ delayTestFinish(5000);
+
+ SimpleFooProxy rayFoo = req.create(SimpleFooProxy.class);
+ final RequestObject<SimpleFooProxy> persistRay = req.simpleFooRequest().persistAndReturnSelf(
+ rayFoo);
+ rayFoo = persistRay.edit(rayFoo);
+ // 42 is the crash causing magic number
+ rayFoo.setPleaseCrash(42);
+
+ persistRay.fire(new Receiver<SimpleFooProxy>() {
+ @Override
+ public void onFailure(ServerFailure error) {
+ assertEquals("test message", error.getMessage());
+ assertEquals("java.lang.UnsupportedOperationException",
+ error.getExceptionType());
+ assertFalse(error.getStackTraceString().isEmpty());
+ finishTestAndReset();
+ }
+
+ @Override
+ public void onViolation(Set<Violation> errors) {
+ fail("Failure expected but onViolation() was called");
+ }
+
+ public void onSuccess(SimpleFooProxy response,
+ Set<SyncResult> syncResult) {
+ fail("Failure expected but onSuccess() was called");
+ }
+ });
+ }
+
+}
diff --git a/user/test/com/google/gwt/requestfactory/client/RequestFactoryTest.java b/user/test/com/google/gwt/requestfactory/client/RequestFactoryTest.java
index 13755ec..b40edef 100644
--- a/user/test/com/google/gwt/requestfactory/client/RequestFactoryTest.java
+++ b/user/test/com/google/gwt/requestfactory/client/RequestFactoryTest.java
@@ -20,6 +20,7 @@
import com.google.gwt.requestfactory.shared.EntityProxyId;
import com.google.gwt.requestfactory.shared.Receiver;
import com.google.gwt.requestfactory.shared.RequestObject;
+import com.google.gwt.requestfactory.shared.ServerFailure;
import com.google.gwt.requestfactory.shared.SimpleBarProxy;
import com.google.gwt.requestfactory.shared.SimpleFooProxy;
import com.google.gwt.requestfactory.shared.SyncResult;
@@ -460,6 +461,37 @@
});
}
+ public void testServerFailure() {
+ delayTestFinish(5000);
+
+ SimpleFooProxy rayFoo = req.create(SimpleFooProxy.class);
+ final RequestObject<SimpleFooProxy> persistRay = req.simpleFooRequest().persistAndReturnSelf(
+ rayFoo);
+ rayFoo = persistRay.edit(rayFoo);
+ // 42 is the crash causing magic number
+ rayFoo.setPleaseCrash(42);
+
+ persistRay.fire(new Receiver<SimpleFooProxy>() {
+ @Override
+ public void onFailure(ServerFailure error) {
+ assertEquals("Server Error: test message", error.getMessage());
+ assertEquals("", error.getExceptionType());
+ assertEquals("", error.getStackTraceString());
+ finishTestAndReset();
+ }
+
+ @Override
+ public void onViolation(Set<Violation> errors) {
+ fail("Failure expected but onViolation() was called");
+ }
+
+ public void onSuccess(SimpleFooProxy response,
+ Set<SyncResult> syncResult) {
+ fail("Failure expected but onSuccess() was called");
+ }
+ });
+ }
+
public void testStableId() {
delayTestFinish(5000);
diff --git a/user/test/com/google/gwt/requestfactory/client/impl/SimpleFooProxyProperties.java b/user/test/com/google/gwt/requestfactory/client/impl/SimpleFooProxyProperties.java
index cbd9ee1..07ba06b 100644
--- a/user/test/com/google/gwt/requestfactory/client/impl/SimpleFooProxyProperties.java
+++ b/user/test/com/google/gwt/requestfactory/client/impl/SimpleFooProxyProperties.java
@@ -68,4 +68,6 @@
static final Property<SimpleFooProxy> fooField = new Property<SimpleFooProxy>(
"fooField", SimpleFooProxy.class);
+
+ static final Property<Integer> pleaseCrash = new Property<Integer>("pleaseCrash", Integer.class);
}
\ No newline at end of file
diff --git a/user/test/com/google/gwt/requestfactory/server/RequestFactoryExceptionHandlerServlet.java b/user/test/com/google/gwt/requestfactory/server/RequestFactoryExceptionHandlerServlet.java
new file mode 100644
index 0000000..689e0d0
--- /dev/null
+++ b/user/test/com/google/gwt/requestfactory/server/RequestFactoryExceptionHandlerServlet.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.requestfactory.server;
+
+import com.google.gwt.requestfactory.shared.ServerFailure;
+
+/**
+ * A RequestFactoryServlet that forwards all exception information.
+ */
+public class RequestFactoryExceptionHandlerServlet
+ extends RequestFactoryServlet {
+ public RequestFactoryExceptionHandlerServlet() {
+ super(new ExceptionHandler() {
+ @Override
+ public ServerFailure createServerFailure(Throwable throwable) {
+ return new ServerFailure(throwable.getMessage(),
+ throwable.getClass().getName(), "my stack trace");
+ }
+ });
+ }
+}
diff --git a/user/test/com/google/gwt/requestfactory/server/SimpleFoo.java b/user/test/com/google/gwt/requestfactory/server/SimpleFoo.java
index 4b25282..f8fdf2c 100644
--- a/user/test/com/google/gwt/requestfactory/server/SimpleFoo.java
+++ b/user/test/com/google/gwt/requestfactory/server/SimpleFoo.java
@@ -125,6 +125,7 @@
private Boolean boolField;
private Boolean otherBoolField;
+ private Integer pleaseCrashField;
private SimpleBar barField;
private SimpleFoo fooField;
@@ -143,6 +144,7 @@
boolField = true;
nullField = null;
barNullField = null;
+ pleaseCrashField = 0;
}
public Long countSimpleFooWithUserNameSideEffect() {
@@ -243,6 +245,10 @@
return password;
}
+ public Integer getPleaseCrash() {
+ return pleaseCrashField;
+ }
+
/**
* @return the shortField
*/
@@ -360,6 +366,13 @@
this.otherBoolField = otherBoolField;
}
+ public void setPleaseCrash(Integer crashIf42) {
+ if (crashIf42 == 42) {
+ throw new UnsupportedOperationException("test message");
+ }
+ pleaseCrashField = crashIf42;
+ }
+
public void setPassword(String password) {
this.password = password;
}
diff --git a/user/test/com/google/gwt/requestfactory/shared/SimpleFooProxy.java b/user/test/com/google/gwt/requestfactory/shared/SimpleFooProxy.java
index 6a22760..1a8e839 100644
--- a/user/test/com/google/gwt/requestfactory/shared/SimpleFooProxy.java
+++ b/user/test/com/google/gwt/requestfactory/shared/SimpleFooProxy.java
@@ -59,6 +59,8 @@
Boolean getOtherBoolField();
+ Integer getPleaseCrash();
+
String getPassword();
Short getShortField();
@@ -97,6 +99,8 @@
void setPassword(String password);
+ void setPleaseCrash(Integer dummy);
+
void setShortField(Short s);
void setUserName(String userName);