Patch to pass java exceptions encountered during JS execution back to Java land.

Patch by: amitmanjhi
Review by: jat(tbr)



git-svn-id: https://google-web-toolkit.googlecode.com/svn/branches/farewellSwt@6148 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/oophm/src/com/google/gwt/dev/shell/HtmlUnitSessionHandler.java b/dev/oophm/src/com/google/gwt/dev/shell/HtmlUnitSessionHandler.java
index e7bb7a7..0bcb130 100644
--- a/dev/oophm/src/com/google/gwt/dev/shell/HtmlUnitSessionHandler.java
+++ b/dev/oophm/src/com/google/gwt/dev/shell/HtmlUnitSessionHandler.java
@@ -30,6 +30,7 @@
 
 import net.sourceforge.htmlunit.corejs.javascript.Context;
 import net.sourceforge.htmlunit.corejs.javascript.Function;
+import net.sourceforge.htmlunit.corejs.javascript.JavaScriptException;
 import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
 import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject;
 import net.sourceforge.htmlunit.corejs.javascript.Undefined;
@@ -63,9 +64,11 @@
       }
       // thisObj is the javaObject.
       Value thisValue = makeValueFromJsval(context, thisObj);
-      return JavaObject.getReturnValueFromJavaMethod(context,
-          HtmlUnitSessionHandler.this, sessionData.getChannel(),
+      ExceptionOrReturnValue returnValue = JavaObject.getReturnFromJavaMethod(
+          context, HtmlUnitSessionHandler.this, sessionData.getChannel(),
           TO_STRING_DISPATCH_ID, thisValue, EMPTY_VALUES);
+      return HtmlUnitSessionHandler.this.makeJsvalFromValue(context,
+          returnValue.getReturnValue());
     }
 
     public Scriptable construct(Context cx, Scriptable scope, Object[] args) {
@@ -200,6 +203,11 @@
     try {
       result = jsEngine.callFunction(htmlPage, jsFunction, jsContext, window,
           jsThis, jsArgs);
+    } catch (JavaScriptException ex) {
+      logger.log(TreeLogger.INFO, "INVOKE: JavaScriptException " + ex
+          + ", message: " + ex.getMessage() + " when invoking " + methodName);
+      return new ExceptionOrReturnValue(true, makeValueFromJsval(jsContext,
+          ex.getValue()));
     } catch (Exception ex) {
       logger.log(TreeLogger.ERROR, "INVOKE: exception " + ex + ", message: "
           + ex.getMessage() + " when invoking " + methodName);
diff --git a/dev/oophm/src/com/google/gwt/dev/shell/JavaObject.java b/dev/oophm/src/com/google/gwt/dev/shell/JavaObject.java
index 6f0b585..74b5a53 100644
--- a/dev/oophm/src/com/google/gwt/dev/shell/JavaObject.java
+++ b/dev/oophm/src/com/google/gwt/dev/shell/JavaObject.java
@@ -19,6 +19,7 @@
 import com.google.gwt.dev.shell.BrowserChannel.JavaObjectRef;
 import com.google.gwt.dev.shell.BrowserChannel.ReturnMessage;
 import com.google.gwt.dev.shell.BrowserChannel.Value;
+import com.google.gwt.dev.shell.BrowserChannel.SessionHandler.ExceptionOrReturnValue;
 
 import net.sourceforge.htmlunit.corejs.javascript.Context;
 import net.sourceforge.htmlunit.corejs.javascript.Function;
@@ -34,6 +35,8 @@
 public class JavaObject extends ScriptableObject implements Function {
 
   private static final long serialVersionUID = -7923090130737830902L;
+  private static final ExceptionOrReturnValue DEFAULT_VALUE = new ExceptionOrReturnValue(
+      true, new Value());
 
   public static JavaObject getOrCreateJavaObject(JavaObjectRef javaRef,
       SessionData sessionData, Context context) {
@@ -41,30 +44,26 @@
         javaRef.getRefid(), context);
   }
 
-  static Object getReturnValueFromJavaMethod(Context cx,
+  static ExceptionOrReturnValue getReturnFromJavaMethod(Context cx,
       HtmlUnitSessionHandler sessionHandler, BrowserChannel channel,
       int dispatchId, Value thisValue, Value valueArgs[]) {
-    ReturnMessage returnMessage = null;
+
     synchronized (sessionHandler.getHtmlPage()) {
       try {
         new InvokeOnServerMessage(channel, dispatchId, thisValue, valueArgs).send();
       } catch (IOException e) {
-        return Undefined.instance;
+        return DEFAULT_VALUE;
       }
       try {
-        returnMessage = ((BrowserChannelClient) channel).reactToMessagesWhileWaitingForReturn(sessionHandler);
+        ReturnMessage returnMessage = ((BrowserChannelClient) channel).reactToMessagesWhileWaitingForReturn(sessionHandler);
+        return new ExceptionOrReturnValue(returnMessage.isException(),
+            returnMessage.getReturnValue());
       } catch (IOException e) {
-        return Undefined.instance;
+        return DEFAULT_VALUE;
       } catch (BrowserChannelException e) {
-        return Undefined.instance;
+        return DEFAULT_VALUE;
       }
     }
-    Value returnValue = returnMessage.getReturnValue();
-    if (returnMessage.isException()) {
-      throw new RuntimeException("JavaObject.call failed, returnMessage: "
-          + returnValue.toString());
-    }
-    return sessionHandler.makeJsvalFromValue(cx, returnValue);
   }
 
   static boolean isJavaObject(Context jsContext, ScriptableObject javaObject) {
@@ -113,15 +112,17 @@
         args[1]);
     int dispatchId = ((Number) args[0]).intValue();
 
+    ExceptionOrReturnValue returnValue = getReturnFromJavaMethod(cx,
+        sessionData.getSessionHandler(), sessionData.getChannel(), dispatchId,
+        thisValue, valueArgs);
     /*
      * Return a object array ret. ret[0] is a boolean indicating whether an
      * exception was thrown or not. ret[1] is the exception or the return value.
-     * If there is an exception, a RuntimeException is thrown.
      */
     Object ret[] = new Object[2];
-    ret[0] = Boolean.FALSE;
-    ret[1] = getReturnValueFromJavaMethod(cx, sessionData.getSessionHandler(),
-        sessionData.getChannel(), dispatchId, thisValue, valueArgs);
+    ret[0] = returnValue.isException();
+    ret[1] = sessionData.getSessionHandler().makeJsvalFromValue(cx,
+        returnValue.getReturnValue());
     return ret;
   }