Skip to content

Commit

Permalink
INTERNAL: stacktrace all exceptions
Browse files Browse the repository at this point in the history
  • Loading branch information
oliviarla committed Nov 21, 2024
1 parent 132254c commit 20bc53a
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 1 deletion.
4 changes: 4 additions & 0 deletions src/main/java/net/spy/memcached/ExceptionMessageFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ private static boolean isBulkOperation(Operation op, Collection<Operation> ops)
}

public static String createCompositeMessage(List<Exception> exceptions) {
if (exceptions == null || exceptions.isEmpty()) {
throw new IllegalArgumentException("At least one exception must be specified");
}

StringBuilder rv = new StringBuilder();
rv.append("Multiple exceptions (");
rv.append(exceptions.size());
Expand Down
42 changes: 41 additions & 1 deletion src/main/java/net/spy/memcached/internal/CompositeException.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package net.spy.memcached.internal;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
Expand All @@ -10,13 +12,51 @@ public class CompositeException extends ExecutionException {

private static final long serialVersionUID = -599478797582490012L;
private final ArrayList<Exception> exceptions = new ArrayList<>();
private final Throwable cause;

CompositeException(List<Exception> exceptions) {
public CompositeException(List<Exception> exceptions) {
super(ExceptionMessageFactory.createCompositeMessage(exceptions));
if (exceptions.size() > 1) {
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter();
sb.append(System.lineSeparator());

for (Exception e : exceptions) {
e.printStackTrace(new PrintWriter(sw));
}

sb.append(sw);
this.cause = new ExceptionOverview(sb.toString());
} else {
this.cause = exceptions.get(0);
}
this.exceptions.addAll(exceptions);
}

public List<Exception> getExceptions() {
return exceptions;
}

public int size() {
return exceptions.size();
}

@Override
public synchronized Throwable getCause() {
return cause;
}

static final class ExceptionOverview extends RuntimeException {

private static final long serialVersionUID = -641960514509105302L;

ExceptionOverview(String message) {
super(message);
}

@Override
public synchronized Throwable fillInStackTrace() {
return this;
}
}
}
15 changes: 15 additions & 0 deletions src/test/java/net/spy/memcached/compat/log/LoggingTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@

// XXX: This really needs to get log4j configured first.

import java.util.ArrayList;
import java.util.List;

import net.spy.memcached.internal.CompositeException;
import net.spy.memcached.ops.OperationErrorType;
import net.spy.memcached.ops.OperationException;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -154,4 +161,12 @@ void testNoExceptionArg() throws Exception {
assertNull(t);
}

@Test
void logCompositeException() {
List<Exception> exceptions = new ArrayList<>();
exceptions.add(new OperationException(OperationErrorType.SERVER, "msg1"));
exceptions.add(new OperationException(OperationErrorType.CLIENT, "msg2"));

logger.error("failed to get", new CompositeException(exceptions));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package net.spy.memcached.internal;

import java.util.ArrayList;
import java.util.List;

import net.spy.memcached.ops.OperationErrorType;
import net.spy.memcached.ops.OperationException;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertTrue;

class CompositeExceptionTest {



@Test
void printStackTraceOfAllExceptions() {
List<Exception> exceptions = new ArrayList<>();
exceptions.add(new OperationException(OperationErrorType.SERVER, "msg1"));
exceptions.add(new OperationException(OperationErrorType.CLIENT, "msg2"));
Exception e = throwError1();
exceptions.add(e);
CompositeException compositeException = new CompositeException(exceptions);
String message = compositeException.getCause().getMessage();

compositeException.printStackTrace();
assertTrue(message
.contains("OperationException: SERVER: msg1"));
assertTrue(message
.contains("OperationException: CLIENT: msg2"));
assertTrue(message
.contains("OperationException: SERVER: msg3"));
assertTrue(message
.contains("at net.spy.memcached.internal.CompositeExceptionTest.throwError2"));
assertTrue(message
.contains("at net.spy.memcached.internal.CompositeExceptionTest.throwError1"));
}

private Exception throwError1() {
return throwError2();
}

private Exception throwError2() {
return new OperationException(OperationErrorType.SERVER, "msg3");
}
}

0 comments on commit 20bc53a

Please sign in to comment.