From 98194e83aa7696f5c0e6dd9e7c025657ea835731 Mon Sep 17 00:00:00 2001 From: Paul Speed Date: Tue, 22 Dec 2015 05:33:44 -0500 Subject: [PATCH] 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. --- .../network/service/rpc/RpcConnection.java | 5 +++ .../service/rpc/msg/RpcResponseMessage.java | 38 ++++++++++++++++--- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/jme3-networking/src/main/java/com/jme3/network/service/rpc/RpcConnection.java b/jme3-networking/src/main/java/com/jme3/network/service/rpc/RpcConnection.java index f457e426b..0ced410c4 100644 --- a/jme3-networking/src/main/java/com/jme3/network/service/rpc/RpcConnection.java +++ b/jme3-networking/src/main/java/com/jme3/network/service/rpc/RpcConnection.java @@ -225,6 +225,7 @@ public class RpcConnection { private class ResponseHolder { private Object response; private String error; + private Throwable exception; private RpcCallMessage msg; boolean received = false; @@ -235,6 +236,7 @@ public class RpcConnection { public synchronized void setResponse( RpcResponseMessage msg ) { this.response = msg.getResult(); this.error = msg.getError(); + this.exception = msg.getThrowable(); this.received = true; notifyAll(); } @@ -250,6 +252,9 @@ public class RpcConnection { if( error != null ) { throw new RuntimeException("Error calling remote procedure:" + msg + "\n" + error); } + if( exception != null ) { + throw new RuntimeException("Error calling remote procedure:" + msg, exception); + } return response; } diff --git a/jme3-networking/src/main/java/com/jme3/network/service/rpc/msg/RpcResponseMessage.java b/jme3-networking/src/main/java/com/jme3/network/service/rpc/msg/RpcResponseMessage.java index c8ca8083a..8e15514e7 100644 --- a/jme3-networking/src/main/java/com/jme3/network/service/rpc/msg/RpcResponseMessage.java +++ b/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.serializing.Serializable; +import com.jme3.network.serializing.Serializer; import java.io.PrintWriter; import java.io.StringWriter; @@ -50,6 +51,7 @@ public class RpcResponseMessage extends AbstractMessage { private long msgId; private Object result; private String error; + private Object exception; // if it was serializable public RpcResponseMessage() { } @@ -61,12 +63,31 @@ public class RpcResponseMessage extends AbstractMessage { public RpcResponseMessage( long msgId, Throwable t ) { 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() { @@ -81,10 +102,15 @@ public class RpcResponseMessage extends AbstractMessage { return error; } + public Throwable getThrowable() { + return (Throwable)exception; + } + @Override public String toString() { return getClass().getSimpleName() + "[#" + msgId + ", result=" + result + (error != null ? ", error=" + error : "") + + (exception != null ? ", exception=" + exception : "") + "]"; } }