summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCaspar De Groot2011-04-05 00:40:42 (EDT)
committerCaspar De Groot2011-04-05 00:40:42 (EDT)
commit5a0323152b0dc43c6028fdbb0d5a9911d477cefb (patch)
tree077db27526d4967821e8e676f218f1f0fc2d1dde
parentb9c1627c2af15f654395b4a3cd16da0b050461f0 (diff)
downloadcdo-5a0323152b0dc43c6028fdbb0d5a9911d477cefb.zip
cdo-5a0323152b0dc43c6028fdbb0d5a9911d477cefb.tar.gz
cdo-5a0323152b0dc43c6028fdbb0d5a9911d477cefb.tar.bz2
[Bug 340725] Make server-side exceptions easier to correlate with their client-side causes
https://bugs.eclipse.org/bugs/show_bug.cgi?id=340725
-rw-r--r--plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/IOUtil.java22
-rw-r--r--plugins/org.eclipse.net4j/src/org/eclipse/net4j/buffer/BufferInputStream.java27
-rw-r--r--plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RemoteException.java39
-rw-r--r--plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RequestWithConfirmation.java13
4 files changed, 87 insertions, 14 deletions
diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/IOUtil.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/IOUtil.java
index 394b314..5f29aff 100644
--- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/IOUtil.java
+++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/IOUtil.java
@@ -96,6 +96,28 @@ public final class IOUtil
return System.err;
}
+ /**
+ * @since 3.1
+ */
+ public static void print(StackTraceElement[] elements)
+ {
+ print(elements, System.err);
+ }
+
+ /**
+ * @since 3.1
+ */
+ public static void print(StackTraceElement[] elements, PrintStream stream)
+ {
+ synchronized (stream)
+ {
+ for (int i = 0; i < elements.length; i++)
+ {
+ stream.println("\tat " + elements[i]);
+ }
+ }
+ }
+
public static void print(Throwable t, PrintStream stream)
{
t.printStackTrace(stream);
diff --git a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/buffer/BufferInputStream.java b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/buffer/BufferInputStream.java
index f0953e2..5e724c5 100644
--- a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/buffer/BufferInputStream.java
+++ b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/buffer/BufferInputStream.java
@@ -10,6 +10,7 @@
*/
package org.eclipse.net4j.buffer;
+import org.eclipse.net4j.signal.RemoteException;
import org.eclipse.net4j.util.HexUtil;
import org.eclipse.net4j.util.WrappedException;
import org.eclipse.net4j.util.io.IOTimeoutException;
@@ -46,7 +47,7 @@ public class BufferInputStream extends InputStream implements IBufferHandler
private boolean eos;
- private RuntimeException exception;
+ private RemoteException exception;
private long stopTimeMillis;
@@ -85,9 +86,9 @@ public class BufferInputStream extends InputStream implements IBufferHandler
}
/**
- * @since 2.0
+ * @since 4.0
*/
- public void setException(RuntimeException exception)
+ public void setException(RemoteException exception)
{
this.exception = exception;
}
@@ -163,10 +164,7 @@ public class BufferInputStream extends InputStream implements IBufferHandler
{
while (currentBuffer == null)
{
- if (exception != null)
- {
- throw exception;
- }
+ throwRemoteExceptionIfExists();
if (buffers == null)
{
@@ -182,10 +180,7 @@ public class BufferInputStream extends InputStream implements IBufferHandler
restartTimeout();
while (currentBuffer == null)
{
- if (exception != null)
- {
- throw exception;
- }
+ throwRemoteExceptionIfExists();
if (buffers == null)
{
@@ -218,4 +213,14 @@ public class BufferInputStream extends InputStream implements IBufferHandler
eos = currentBuffer.isEOS();
return true;
}
+
+ private void throwRemoteExceptionIfExists()
+ {
+ if (exception != null)
+ {
+ StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
+ exception.setLocalStacktrace(stackTrace);
+ throw exception;
+ }
+ }
}
diff --git a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RemoteException.java b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RemoteException.java
index a444a7f..a036611 100644
--- a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RemoteException.java
+++ b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RemoteException.java
@@ -20,9 +20,17 @@ public class RemoteException extends RuntimeException
private boolean whileResponding;
- public RemoteException(Throwable cause, boolean whileResponding)
+ private transient RequestWithConfirmation<?> localRequest;
+
+ private StackTraceElement[] localStackTrace;
+
+ /**
+ * @since 4.0
+ */
+ public RemoteException(Throwable remoteCause, RequestWithConfirmation<?> localRequest, boolean whileResponding)
{
- super(cause);
+ super(remoteCause);
+ this.localRequest = localRequest;
this.whileResponding = whileResponding;
}
@@ -36,4 +44,31 @@ public class RemoteException extends RuntimeException
{
return whileResponding;
}
+
+ /**
+ * @since 4.0
+ */
+ public RequestWithConfirmation<?> getLocalRequest()
+ {
+ return localRequest;
+ }
+
+ /**
+ * @since 4.0
+ */
+ public void setLocalStacktrace(StackTraceElement[] stackTrace)
+ {
+ localStackTrace = stackTrace;
+ }
+
+ /**
+ * Returns the local stack as it stood at the time that the <i>remote</i> exception was detected <i>locally</i>. Note
+ * that no local problem occurred at the point in the code identified by this stacktrace.
+ *
+ * @since 4.0
+ */
+ public StackTraceElement[] getLocalStackTrace()
+ {
+ return localStackTrace;
+ }
}
diff --git a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RequestWithConfirmation.java b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RequestWithConfirmation.java
index 8fb539f..95c4710 100644
--- a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RequestWithConfirmation.java
+++ b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/signal/RequestWithConfirmation.java
@@ -125,6 +125,17 @@ public abstract class RequestWithConfirmation<RESULT> extends SignalActor
void setRemoteException(Throwable t, boolean responding)
{
- getBufferInputStream().setException(new RemoteException(t, responding));
+ RemoteException remoteException = getRemoteException(t, responding);
+ getBufferInputStream().setException(remoteException);
+ }
+
+ private RemoteException getRemoteException(Throwable t, boolean responding)
+ {
+ if (t instanceof RemoteException)
+ {
+ return (RemoteException)t;
+ }
+
+ return new RemoteException(t, this, responding);
}
}