Skip to content

Commit

Permalink
Support suppressed exceptions in throwable converter
Browse files Browse the repository at this point in the history
  • Loading branch information
ash2k committed Sep 22, 2013
1 parent 54b0aa8 commit c660535
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 33 deletions.
Expand Up @@ -34,6 +34,8 @@
*/
public class ThrowableProxyConverter extends ThrowableHandlingConverter {

protected static final int BUILDER_CAPACITY = 2048;

int lengthOption;
List<EventEvaluator<ILoggingEvent>> evaluatorList = null;

Expand Down Expand Up @@ -137,18 +139,41 @@ public String convert(ILoggingEvent event) {
}

protected String throwableProxyToString(IThrowableProxy tp) {
StringBuilder buf = new StringBuilder(32);
IThrowableProxy currentThrowable = tp;
while (currentThrowable != null) {
subjoinThrowableProxy(buf, currentThrowable);
currentThrowable = currentThrowable.getCause();
StringBuilder sb = new StringBuilder(BUILDER_CAPACITY);

recursiveAppend(sb, null, ThrowableProxyUtil.REGULAR_EXCEPTION_INDENT, tp);

return sb.toString();
}

private void recursiveAppend(StringBuilder sb, String prefix, int indent, IThrowableProxy tp) {
if(tp == null)
return;
subjoinFirstLine(sb, prefix, indent, tp);
sb.append(CoreConstants.LINE_SEPARATOR);
subjoinSTEPArray(sb, indent, tp);
IThrowableProxy[] suppressed = tp.getSuppressed();
if(suppressed != null) {
for(IThrowableProxy current : suppressed) {
recursiveAppend(sb, CoreConstants.SUPPRESSED, indent + ThrowableProxyUtil.SUPPRESSED_EXCEPTION_INDENT, current);
}
}
return buf.toString();
recursiveAppend(sb, CoreConstants.CAUSED_BY, indent, tp.getCause());
}

private void subjoinFirstLine(StringBuilder buf, String prefix, int indent, IThrowableProxy tp) {
ThrowableProxyUtil.indent(buf, indent - 1);
if (prefix != null) {
buf.append(prefix);
}
subjoinExceptionMessage(buf, tp);
}

private void subjoinExceptionMessage(StringBuilder buf, IThrowableProxy tp) {
buf.append(tp.getClassName()).append(": ").append(tp.getMessage());
}

void subjoinThrowableProxy(StringBuilder buf, IThrowableProxy tp) {
ThrowableProxyUtil.subjoinFirstLine(buf, tp);
buf.append(CoreConstants.LINE_SEPARATOR);
private void subjoinSTEPArray(StringBuilder buf, int indent, IThrowableProxy tp) {
StackTraceElementProxy[] stepArray = tp.getStackTraceElementProxyArray();
int commonFrames = tp.getCommonFrames();

Expand All @@ -161,15 +186,15 @@ void subjoinThrowableProxy(StringBuilder buf, IThrowableProxy tp) {
}

for (int i = 0; i < maxIndex; i++) {
String string = stepArray[i].toString();
buf.append(CoreConstants.TAB);
buf.append(string);
ThrowableProxyUtil.indent(buf, indent);
buf.append(stepArray[i]);
extraData(buf, stepArray[i]); // allow other data to be added
buf.append(CoreConstants.LINE_SEPARATOR);
}

if (commonFrames > 0 && unrestrictedPrinting) {
buf.append("\t... ").append(tp.getCommonFrames()).append(
ThrowableProxyUtil.indent(buf, indent);
buf.append("... ").append(tp.getCommonFrames()).append(
" common frames omitted").append(CoreConstants.LINE_SEPARATOR);
}
}
Expand Down
Expand Up @@ -17,14 +17,15 @@

/**
* Convert a throwable into an array of ThrowableDataPoint objects.
*
*
*
*
* @author Ceki G&uuml;lc&uuml;
*/
public class ThrowableProxyUtil {

public static final int REGULAR_EXCEPTION_INDENT = 1;
public static final int SUPPRESSED_EXCEPTION_INDENT = 2;
public static final int SUPPRESSED_EXCEPTION_INDENT = 1;
private static final int BUILDER_CAPACITY = 2048;

public static void build(ThrowableProxy nestedTP, Throwable nestedThrowable,
ThrowableProxy parentTP) {
Expand Down Expand Up @@ -76,7 +77,7 @@ static int findNumberOfCommonFrames(StackTraceElement[] steArray,
}

public static String asString(IThrowableProxy tp) {
StringBuilder sb = new StringBuilder();
StringBuilder sb = new StringBuilder(BUILDER_CAPACITY);

recursiveAppend(sb, null, REGULAR_EXCEPTION_INDENT, tp);

Expand All @@ -86,19 +87,26 @@ public static String asString(IThrowableProxy tp) {
private static void recursiveAppend(StringBuilder sb, String prefix, int indent, IThrowableProxy tp) {
if(tp == null)
return;
subjoinFirstLine(sb, prefix, tp);
subjoinFirstLine(sb, prefix, indent, tp);
sb.append(CoreConstants.LINE_SEPARATOR);
subjoinSTEPArray(sb, indent, tp);
IThrowableProxy[] suppressed = tp.getSuppressed();
if(suppressed != null) {
for(IThrowableProxy current : suppressed) {
recursiveAppend(sb, CoreConstants.SUPPRESSED, SUPPRESSED_EXCEPTION_INDENT, current);
recursiveAppend(sb, CoreConstants.SUPPRESSED, indent + SUPPRESSED_EXCEPTION_INDENT, current);
}
}
recursiveAppend(sb, CoreConstants.CAUSED_BY, REGULAR_EXCEPTION_INDENT, tp.getCause());
recursiveAppend(sb, CoreConstants.CAUSED_BY, indent, tp.getCause());
}

public static void indent(StringBuilder buf, int indent) {
for(int j = 0; j < indent; j++) {
buf.append(CoreConstants.TAB);
}
}

private static void subjoinFirstLine(StringBuilder buf, String prefix, IThrowableProxy tp) {
private static void subjoinFirstLine(StringBuilder buf, String prefix, int indent, IThrowableProxy tp) {
indent(buf, indent - 1);
if (prefix != null) {
buf.append(prefix);
}
Expand All @@ -114,13 +122,13 @@ public static void subjoinPackagingData(StringBuilder builder, StackTraceElement
} else {
builder.append(" [");
}

builder.append(cpd.getCodeLocation()).append(':').append(
cpd.getVersion()).append(']');
}
}
}

public static void subjoinSTEP(StringBuilder sb, StackTraceElementProxy step) {
sb.append(step.toString());
subjoinPackagingData(sb, step);
Expand All @@ -138,7 +146,7 @@ public static void subjoinSTEPArray(StringBuilder sb, IThrowableProxy tp) {

/**
* @param sb The StringBuilder the STEPs are appended to.
* @param indentLevel indentation level used for the STEPs, usually either REGULAR_EXCEPTION_INDENT or SUPPRESSED_EXCEPTION_INDENT.
* @param indentLevel indentation level used for the STEPs, usually REGULAR_EXCEPTION_INDENT.
* @param tp the IThrowableProxy containing the STEPs.
*/
public static void subjoinSTEPArray(StringBuilder sb, int indentLevel, IThrowableProxy tp) {
Expand All @@ -147,21 +155,17 @@ public static void subjoinSTEPArray(StringBuilder sb, int indentLevel, IThrowabl

for (int i = 0; i < stepArray.length - commonFrames; i++) {
StackTraceElementProxy step = stepArray[i];
for(int j = 0; j < indentLevel ; j++) {
sb.append(CoreConstants.TAB);
}
indent(sb, indentLevel);
subjoinSTEP(sb, step);
sb.append(CoreConstants.LINE_SEPARATOR);
}

if (commonFrames > 0) {
for(int j = 0; j < indentLevel ; j++) {
sb.append(CoreConstants.TAB);
}
indent(sb, indentLevel);
sb.append("... ").append(commonFrames).append(" common frames omitted")
.append(CoreConstants.LINE_SEPARATOR);
}

}

public static void subjoinFirstLine(StringBuilder buf, IThrowableProxy tp) {
Expand Down
Expand Up @@ -127,6 +127,23 @@ public void suppressedWithCause() throws InvocationTargetException, IllegalAcces
verify(ex);
}

@Test
public void suppressedWithSuppressed() throws Exception
{
assumeNotNull(ADD_SUPPRESSED_METHOD); // only execute on Java 7, would work anyway but doesn't make sense.
Exception ex = null;
try {
someMethod();
} catch (Exception e) {
ex=new Exception("Wrapper", e);
Exception fooException = new Exception("Foo");
Exception barException = new Exception("Bar");
addSuppressed(barException, fooException);
addSuppressed(e, barException);
}
verify(ex);
}

// see also http://jira.qos.ch/browse/LBCLASSIC-216
@Test
public void nullSTE() {
Expand Down
Expand Up @@ -85,7 +85,7 @@ public class CoreConstants {
*/
public static final Class<?>[] EMPTY_CLASS_ARRAY = new Class[]{};
public static final String CAUSED_BY = "Caused by: ";
public static final String SUPPRESSED = "\tSuppressed: ";
public static final String SUPPRESSED = "Suppressed: ";
public static final String WRAPPED_BY = "Wrapped by: ";

public static final char PERCENT_CHAR = '%';
Expand Down

0 comments on commit c660535

Please sign in to comment.