2
0
Эх сурвалжийг харах

Modified the RPC layer to pass exceptions over the wire
if they are serializable. They are still wrapped but at
least the original exception is intact if callers want to
peel it out.

Paul Speed 9 жил өмнө
parent
commit
98194e83aa

+ 5 - 0
jme3-networking/src/main/java/com/jme3/network/service/rpc/RpcConnection.java

@@ -225,6 +225,7 @@ public class RpcConnection {
     private class ResponseHolder {
     private class ResponseHolder {
         private Object response;
         private Object response;
         private String error;
         private String error;
+        private Throwable exception;
         private RpcCallMessage msg;
         private RpcCallMessage msg;
         boolean received = false;
         boolean received = false;
  
  
@@ -235,6 +236,7 @@ public class RpcConnection {
         public synchronized void setResponse( RpcResponseMessage msg ) {
         public synchronized void setResponse( RpcResponseMessage msg ) {
             this.response = msg.getResult();
             this.response = msg.getResult();
             this.error = msg.getError();
             this.error = msg.getError();
+            this.exception = msg.getThrowable();
             this.received = true;
             this.received = true;
             notifyAll();
             notifyAll();
         }
         }
@@ -250,6 +252,9 @@ public class RpcConnection {
             if( error != null ) {
             if( error != null ) {
                 throw new RuntimeException("Error calling remote procedure:" + msg + "\n" + error);
                 throw new RuntimeException("Error calling remote procedure:" + msg + "\n" + error);
             }
             }
+            if( exception != null ) {
+                throw new RuntimeException("Error calling remote procedure:" + msg, exception);
+            } 
             return response;              
             return response;              
         }
         }
         
         

+ 32 - 6
jme3-networking/src/main/java/com/jme3/network/service/rpc/msg/RpcResponseMessage.java

@@ -34,6 +34,7 @@ package com.jme3.network.service.rpc.msg;
 
 
 import com.jme3.network.AbstractMessage;
 import com.jme3.network.AbstractMessage;
 import com.jme3.network.serializing.Serializable;
 import com.jme3.network.serializing.Serializable;
+import com.jme3.network.serializing.Serializer;
 import java.io.PrintWriter;
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.io.StringWriter;
 
 
@@ -50,6 +51,7 @@ public class RpcResponseMessage extends AbstractMessage {
     private long msgId;
     private long msgId;
     private Object result;
     private Object result;
     private String error;
     private String error;
+    private Object exception; // if it was serializable
 
 
     public RpcResponseMessage() {
     public RpcResponseMessage() {
     }
     }
@@ -61,12 +63,31 @@ public class RpcResponseMessage extends AbstractMessage {
 
 
     public RpcResponseMessage( long msgId, Throwable t ) {
     public RpcResponseMessage( long msgId, Throwable t ) {
         this.msgId = msgId;
         this.msgId = msgId;
-         
-        StringWriter sOut = new StringWriter();
-        PrintWriter out = new PrintWriter(sOut);
-        t.printStackTrace(out);
-        out.close();
-        this.error = sOut.toString();
+ 
+        // See if the exception is serializable
+        if( isSerializable(t) ) {
+            // Can send the exception itself
+            this.exception = t;
+        } else {
+            // We'll compose all of the info into a string           
+            StringWriter sOut = new StringWriter();
+            PrintWriter out = new PrintWriter(sOut);
+            t.printStackTrace(out);
+            out.close();
+            this.error = sOut.toString();
+        }
+    }
+ 
+    public static boolean isSerializable( Throwable error ) {
+        if( error == null ) {
+            return false;
+        }
+        for( Throwable t = error; t != null; t = t.getCause() ) {
+            if( Serializer.getExactSerializerRegistration(t.getClass()) == null ) {
+                return false;
+            }
+        }
+        return true; 
     }
     }
  
  
     public long getMessageId() {
     public long getMessageId() {
@@ -81,10 +102,15 @@ public class RpcResponseMessage extends AbstractMessage {
         return error;
         return error;
     }
     }
     
     
+    public Throwable getThrowable() {
+        return (Throwable)exception;
+    }
+    
     @Override
     @Override
     public String toString() {
     public String toString() {
         return getClass().getSimpleName() + "[#" + msgId + ", result=" + result
         return getClass().getSimpleName() + "[#" + msgId + ", result=" + result
                                           + (error != null ? ", error=" + error : "")
                                           + (error != null ? ", error=" + error : "")
+                                          + (exception != null ? ", exception=" + exception : "")
                                           + "]";
                                           + "]";
     }
     }
 }
 }