Added error handling for exceptions that can occur when logging messages are sent over the wire from DevMode to GPE.
Review at http://gwt-code-reviews.appspot.com/1149801

Review by: scottb@google.com

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9303 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/shell/remoteui/MessageTransport.java b/dev/core/src/com/google/gwt/dev/shell/remoteui/MessageTransport.java
index 903511d..76fd9f4 100644
--- a/dev/core/src/com/google/gwt/dev/shell/remoteui/MessageTransport.java
+++ b/dev/core/src/com/google/gwt/dev/shell/remoteui/MessageTransport.java
@@ -44,6 +44,25 @@
 public class MessageTransport {
 
   /**
+   * A callback that is invoked when errors occur at the transport level.
+   */
+  public interface ErrorCallback {
+
+    /**
+     * Called when an exception occurs when attempting to send a response
+     * message. 
+     */
+    void onResponseException(Exception e);
+
+    /**
+     * Called when the transport terminates due to an exception.
+     * 
+     * @param e The exception that led to the termination
+     */
+    void onTermination(Exception e);
+  }
+
+  /**
    * An exception that is generated by the transport when it receives a failure
    * message from the server in response to executing a client request.
    */
@@ -70,19 +89,6 @@
     }
   }
 
-  /**
-   * A callback that is invoked when the transport terminates.
-   */
-  public interface TerminationCallback {
-
-    /**
-     * Called when the transport terminates.
-     * 
-     * @param e The exception that led to the termination
-     */
-    void onTermination(Exception e);
-  }
-
   class PendingRequest extends PendingSend {
     private final Callback<Response> callback;
     private final Message message;
@@ -169,7 +175,9 @@
 
     @Override
     public void failed(Exception e) {
-      // Do nothing
+      if (errorCallback != null) {
+        errorCallback.onResponseException(e);
+      }
     }
 
     @Override
@@ -200,7 +208,7 @@
   private final RequestProcessor requestProcessor;
   private final LinkedBlockingQueue<PendingSend> sendQueue = new LinkedBlockingQueue<PendingSend>();
 
-  private final TerminationCallback terminationCallback;
+  private final ErrorCallback errorCallback;
 
   /**
    * Create a new instance using the given streams and request processor.
@@ -214,9 +222,9 @@
    */
   public MessageTransport(final InputStream inputStream,
       final OutputStream outputStream, RequestProcessor requestProcessor,
-      TerminationCallback terminationCallback) {
+      ErrorCallback errorCallback) {
     this.requestProcessor = requestProcessor;
-    this.terminationCallback = terminationCallback;
+    this.errorCallback = errorCallback;
     this.inputStream = inputStream;
     this.outputStream = outputStream;
   }
@@ -403,8 +411,7 @@
       }
 
       default: {
-        processUnknownMessageType(message.getMessageId(),
-            messageType.name());
+        processUnknownMessageType(message.getMessageId(), messageType.name());
         break;
       }
     }
@@ -444,8 +451,8 @@
 
   private void terminateDueToException(Exception e) {
     pendingRequestMap.blockAdds(e);
-    if (terminationCallback != null) {
-      terminationCallback.onTermination(e);
+    if (errorCallback != null) {
+      errorCallback.onTermination(e);
     }
   }
 }
diff --git a/dev/core/src/com/google/gwt/dev/shell/remoteui/RemoteUI.java b/dev/core/src/com/google/gwt/dev/shell/remoteui/RemoteUI.java
index d69d69c..abd17e8 100644
--- a/dev/core/src/com/google/gwt/dev/shell/remoteui/RemoteUI.java
+++ b/dev/core/src/com/google/gwt/dev/shell/remoteui/RemoteUI.java
@@ -39,7 +39,7 @@
  * development mode server.
  */
 public class RemoteUI extends DevModeUI implements
-    MessageTransport.TerminationCallback {
+    MessageTransport.ErrorCallback {
 
   private final String clientId;
   private final DevModeServiceRequestProcessor devModeRequestProcessor;
@@ -129,15 +129,20 @@
     // resolved, we send the startup URLs as part of the moduleLoadComplete so
     // they are not displayed before the server is ready to serve the modules at
     // the URLs.
-    viewerServiceClient = new ViewerServiceClient(transport);
+    viewerServiceClient = new ViewerServiceClient(transport, getTopLogger());
     viewerServiceClient.initialize(clientId, cachedStartupUrls);
     viewerServiceClient.checkCapabilities();
   }
 
+  public void onResponseException(Exception e) {
+    getTopLogger().log(TreeLogger.INFO,
+        "An exception occured while attempting to send a response message.", e);   
+  }
+
   public void onTermination(Exception e) {
-    getTopLogger().log(TreeLogger.INFO,
+    getConsoleLogger().log(TreeLogger.INFO,
         "Remote UI connection terminated due to exception: " + e);
-    getTopLogger().log(TreeLogger.INFO,
+    getConsoleLogger().log(TreeLogger.INFO,
         "Shutting down development mode server.");
 
     try {
diff --git a/dev/core/src/com/google/gwt/dev/shell/remoteui/ViewerServiceClient.java b/dev/core/src/com/google/gwt/dev/shell/remoteui/ViewerServiceClient.java
index 820adfc..ee26897 100644
--- a/dev/core/src/com/google/gwt/dev/shell/remoteui/ViewerServiceClient.java
+++ b/dev/core/src/com/google/gwt/dev/shell/remoteui/ViewerServiceClient.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.dev.shell.remoteui;
 
+import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.core.ext.TreeLogger.HelpInfo;
 import com.google.gwt.core.ext.TreeLogger.Type;
 import com.google.gwt.dev.protobuf.ByteString;
@@ -42,16 +43,8 @@
  */
 public class ViewerServiceClient {
 
-  private static final Callback<Response> DUMMY_CALLBACK = new Callback<Response>() {
-    public void onDone(Response result) {
-    }
-
-    public void onError(Throwable t) {
-      // TODO(rdayal): handle errors?
-    }
-  };
-
   private final MessageTransport transport;
+  private final TreeLogger unexpectedErrorLogger;
 
   /**
    * Create a new instance.
@@ -59,8 +52,10 @@
    * @param processor A MessageProcessor that is used to communicate with the
    *          ViewerService server.
    */
-  public ViewerServiceClient(MessageTransport processor) {
+  public ViewerServiceClient(MessageTransport processor,
+      TreeLogger unexpectedErrorLogger) {
     this.transport = processor;
+    this.unexpectedErrorLogger = unexpectedErrorLogger;
   }
 
   /**
@@ -135,7 +130,15 @@
     Request requestMessage = buildRequestMessageFromViewerRequest(
         viewerRequestBuilder).build();
 
-    transport.executeRequestAsync(requestMessage, DUMMY_CALLBACK);
+    transport.executeRequestAsync(requestMessage, new Callback<Response>() {
+      public void onDone(Response result) {
+      }
+
+      public void onError(Throwable t) {
+        unexpectedErrorLogger.log(TreeLogger.WARN,
+            "An error occurred while attempting to add a log entry.", t);
+      }
+    });
   }
 
   /**
@@ -326,7 +329,8 @@
    * 
    * @throws RequestException if the request failed
    */
-  private Response waitForResponse(Future<Response> future) throws RequestException {
+  private Response waitForResponse(Future<Response> future)
+      throws RequestException {
     try {
       return future.get();
     } catch (ExecutionException e) {
@@ -344,7 +348,8 @@
   /**
    * Waits for response and throws an unchecked exception if the request failed.
    */
-  private Response waitForResponseOrThrowUncheckedException(Future<Response> future) {
+  private Response waitForResponseOrThrowUncheckedException(
+      Future<Response> future) {
     try {
       return waitForResponse(future);
     } catch (RequestException e) {
diff --git a/dev/core/src/com/google/gwt/dev/shell/remoteui/ViewerServiceTreeLogger.java b/dev/core/src/com/google/gwt/dev/shell/remoteui/ViewerServiceTreeLogger.java
index 898bc37..6e8e3bb 100644
--- a/dev/core/src/com/google/gwt/dev/shell/remoteui/ViewerServiceTreeLogger.java
+++ b/dev/core/src/com/google/gwt/dev/shell/remoteui/ViewerServiceTreeLogger.java
@@ -146,7 +146,8 @@
           }
 
           public void onError(Throwable t) {
-            // TODO(rdayal): handle errors?
+            System.err.println("An error occurred while attempting to add a log branch.");
+            t.printStackTrace(System.err);
           }
         });
   }
diff --git a/dev/core/test/com/google/gwt/dev/shell/remoteui/MessageTransportTest.java b/dev/core/test/com/google/gwt/dev/shell/remoteui/MessageTransportTest.java
index 8a32250..3d93795 100644
--- a/dev/core/test/com/google/gwt/dev/shell/remoteui/MessageTransportTest.java
+++ b/dev/core/test/com/google/gwt/dev/shell/remoteui/MessageTransportTest.java
@@ -100,7 +100,9 @@
     MessageTransport messageTransport = new MessageTransport(
         network.getClientSocket().getInputStream(),
         network.getClientSocket().getOutputStream(), requestProcessor,
-        new MessageTransport.TerminationCallback() {
+        new MessageTransport.ErrorCallback() {
+          public void onResponseException(Exception e) {
+          }
           public void onTermination(Exception e) {
           }
         });
@@ -246,7 +248,9 @@
     MessageTransport messageTransport = new MessageTransport(
         network.getClientSocket().getInputStream(),
         network.getClientSocket().getOutputStream(), requestProcessor,
-        new MessageTransport.TerminationCallback() {
+        new MessageTransport.ErrorCallback() {
+          public void onResponseException(Exception e) {
+          }
           public void onTermination(Exception e) {
           }
         });
@@ -340,7 +344,9 @@
     MessageTransport messageTransport = new MessageTransport(
         network.getClientSocket().getInputStream(),
         network.getClientSocket().getOutputStream(), requestProcessor,
-        new MessageTransport.TerminationCallback() {
+        new MessageTransport.ErrorCallback() {
+          public void onResponseException(Exception e) {
+          }
           public void onTermination(Exception e) {
           }
         });
@@ -395,7 +401,9 @@
     MessageTransport messageTransport = new MessageTransport(
         network.getClientSocket().getInputStream(),
         network.getClientSocket().getOutputStream(), requestProcessor,
-        new MessageTransport.TerminationCallback() {
+        new MessageTransport.ErrorCallback() {
+          public void onResponseException(Exception e) {
+          }
           public void onTermination(Exception e) {
           }
         });