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.
This commit is contained in:
Paul Speed 2015-12-22 05:33:44 -05:00
parent fd4f9789cc
commit 98194e83aa
2 changed files with 37 additions and 6 deletions

View File

@ -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;
}

View File

@ -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() {
}
@ -62,12 +64,31 @@ public class RpcResponseMessage extends AbstractMessage {
public RpcResponseMessage( long msgId, Throwable t ) {
this.msgId = msgId;
// 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() {
return msgId;
@ -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 : "")
+ "]";
}
}