Add contexted stackoverflow error
This commit is contained in:
5 files changed
+124
-32
No files matched your search
@@ -142,6 +142,10 @@ public final class AssertionUtil {
|
||||
return ContextedAssertionError.wrap(e);
|
||||
}
|
||||
|
||||
public static @NonNull ContextedStackOverflowError contexted(StackOverflowError e) {
|
||||
return ContextedStackOverflowError.wrap(e);
|
||||
}
|
||||
|
||||
public static @NonNull ContextedRuntimeException contexted(RuntimeException e) {
|
||||
return e instanceof ContextedRuntimeException ? (ContextedRuntimeException) e
|
||||
: new ContextedRuntimeException(e);
|
||||
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.internal.util;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang3.exception.DefaultExceptionContext;
|
||||
import org.apache.commons.lang3.exception.ExceptionContext;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
/**
|
||||
* A {@link StackOverflowError} with nice messages.
|
||||
*/
|
||||
public final class ContextedStackOverflowError extends StackOverflowError implements ExceptionContext {
|
||||
|
||||
private final ExceptionContext exceptionContext = new DefaultExceptionContext();
|
||||
|
||||
private ContextedStackOverflowError(StackOverflowError e) {
|
||||
super(e.getMessage());
|
||||
setStackTrace(e.getStackTrace()); // pretend we're a regular assertion error
|
||||
}
|
||||
|
||||
|
||||
public static ContextedStackOverflowError wrap(StackOverflowError e) {
|
||||
return e instanceof ContextedStackOverflowError ? (ContextedStackOverflowError) e
|
||||
: new ContextedStackOverflowError(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return getFormattedExceptionMessage(super.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContextedStackOverflowError addContextValue(String label, Object value) {
|
||||
exceptionContext.addContextValue(label, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContextedStackOverflowError setContextValue(String label, Object value) {
|
||||
exceptionContext.addContextValue(label, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Object> getContextValues(String label) {
|
||||
return exceptionContext.getContextValues(label);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getFirstContextValue(String label) {
|
||||
return exceptionContext.getFirstContextValue(label);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getContextLabels() {
|
||||
return exceptionContext.getContextLabels();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Pair<String, Object>> getContextEntries() {
|
||||
return exceptionContext.getContextEntries();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormattedExceptionMessage(String baseMessage) {
|
||||
return exceptionContext.getFormattedExceptionMessage(baseMessage);
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,8 @@ import java.util.Iterator;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.apache.commons.lang3.exception.ExceptionContext;
|
||||
|
||||
import net.sourceforge.pmd.Report.ProcessingError;
|
||||
import net.sourceforge.pmd.Rule;
|
||||
import net.sourceforge.pmd.RuleContext;
|
||||
@@ -63,25 +65,25 @@ public class RuleApplicator {
|
||||
rule.apply(node, ctx);
|
||||
rcto.close(1);
|
||||
} catch (RuntimeException e) {
|
||||
reportOrRethrow(ctx, rule, node, e, ctx.isIgnoreExceptions());
|
||||
} catch (AssertionError | StackOverflowError e) {
|
||||
reportOrRethrow(ctx, rule, node, e, SystemProps.isErrorRecoveryMode());
|
||||
reportOrRethrow(ctx, rule, node, AssertionUtil.contexted(e), ctx.isIgnoreExceptions());
|
||||
} catch (StackOverflowError e) {
|
||||
reportOrRethrow(ctx, rule, node, AssertionUtil.contexted(e), SystemProps.isErrorRecoveryMode());
|
||||
} catch (AssertionError e) {
|
||||
reportOrRethrow(ctx, rule, node, AssertionUtil.contexted(e), SystemProps.isErrorRecoveryMode());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private <E extends Throwable> void reportOrRethrow(RuleContext ctx, Rule rule, Node node, E e, boolean reportAndDontThrow) throws E {
|
||||
if (e instanceof ExceptionContext) {
|
||||
((ExceptionContext) e).addContextValue("Rule applied on node", node);
|
||||
}
|
||||
|
||||
if (reportAndDontThrow) {
|
||||
reportException(ctx, rule, node, e);
|
||||
} else {
|
||||
if (e instanceof RuntimeException) {
|
||||
throw AssertionUtil.contexted((RuntimeException) e).addContextValue("Rule applied on node", node);
|
||||
} else if (e instanceof AssertionError) {
|
||||
throw AssertionUtil.contexted((AssertionError) e).addContextValue("Rule applied on node", node);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,11 @@ package net.sourceforge.pmd;
|
||||
|
||||
import static net.sourceforge.pmd.util.CollectionUtil.listOf;
|
||||
import static net.sourceforge.pmd.util.CollectionUtil.setOf;
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
@@ -492,7 +497,7 @@ public class RuleSetTest {
|
||||
.addRule(new MockRule() {
|
||||
@Override
|
||||
public void apply(Node nodes, RuleContext ctx) {
|
||||
throw new RuntimeException("Test exception while applying rule");
|
||||
throw new IllegalStateException("Test exception while applying rule");
|
||||
}
|
||||
})
|
||||
.build();
|
||||
@@ -504,10 +509,11 @@ public class RuleSetTest {
|
||||
ruleset.apply(makeCompilationUnits(), context);
|
||||
|
||||
List<ProcessingError> errors = context.getReport().getProcessingErrors();
|
||||
assertTrue("Report should have processing errors", !errors.isEmpty());
|
||||
assertEquals("Errors expected", 1, errors.size());
|
||||
assertEquals("Wrong error message", "RuntimeException: Test exception while applying rule", errors.get(0).getMsg());
|
||||
assertTrue("Should be a RuntimeException", errors.get(0).getError() instanceof RuntimeException);
|
||||
assertThat(errors, hasSize(1));
|
||||
ProcessingError error = errors.get(0);
|
||||
assertThat(error.getMsg(), containsString("java.lang.IllegalStateException: Test exception while applying rule\n"));
|
||||
assertThat(error.getMsg(), containsString("Rule applied on node=Foo"));
|
||||
assertThat(error.getError().getCause(), instanceOf(IllegalStateException.class));
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
@@ -533,7 +539,7 @@ public class RuleSetTest {
|
||||
RuleSet ruleset = createRuleSetBuilder("ruleExceptionShouldBeReported").addRule(new MockRule() {
|
||||
@Override
|
||||
public void apply(Node target, RuleContext ctx) {
|
||||
throw new RuntimeException("Test exception while applying rule");
|
||||
throw new IllegalStateException("Test exception while applying rule");
|
||||
}
|
||||
}).addRule(new MockRule() {
|
||||
@Override
|
||||
@@ -549,16 +555,14 @@ public class RuleSetTest {
|
||||
ruleset.apply(makeCompilationUnits(), context);
|
||||
|
||||
List<ProcessingError> errors = context.getReport().getProcessingErrors();
|
||||
assertFalse("Report should have processing errors", errors.isEmpty());
|
||||
assertEquals("Errors expected", 1, errors.size());
|
||||
ProcessingError processingError = errors.get(0);
|
||||
assertEquals("Wrong error message", "RuntimeException: Test exception while applying rule", processingError.getMsg());
|
||||
assertTrue("Should be a RuntimeException", processingError.getError() instanceof RuntimeException);
|
||||
assertEquals("Wrong filename in processing error",
|
||||
"net.sourceforge.pmd.RuleSetTest/ruleExceptionShouldBeReported.java",
|
||||
FilenameUtils.normalize(processingError.getFile(), true));
|
||||
assertThat(errors, hasSize(1));
|
||||
ProcessingError error = errors.get(0);
|
||||
assertThat(error.getMsg(), containsString("java.lang.IllegalStateException: Test exception while applying rule\n"));
|
||||
assertThat(error.getMsg(), containsString("Rule applied on node=Foo"));
|
||||
assertThat(error.getError().getCause(), instanceOf(IllegalStateException.class));
|
||||
assertThat(FilenameUtils.normalize(error.getFile(), true), equalTo("net.sourceforge.pmd.RuleSetTest/ruleExceptionShouldBeReported.java"));
|
||||
|
||||
assertEquals("There should be a violation", 1, context.getReport().getViolations().size());
|
||||
assertThat(context.getReport().getViolations(), hasSize(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -572,7 +576,7 @@ public class RuleSetTest {
|
||||
|
||||
@Override
|
||||
public void apply(Node target, RuleContext ctx) {
|
||||
throw new RuntimeException("Test exception while applying rule");
|
||||
throw new UnsupportedOperationException("Test exception while applying rule");
|
||||
}
|
||||
}).addRule(new MockRule() {
|
||||
|
||||
@@ -595,11 +599,13 @@ public class RuleSetTest {
|
||||
rulesets.apply(makeCompilationUnits(), context);
|
||||
|
||||
List<ProcessingError> errors = context.getReport().getProcessingErrors();
|
||||
assertEquals("Errors expected", 1, errors.size());
|
||||
assertEquals("Wrong error message", "RuntimeException: Test exception while applying rule", errors.get(0).getMsg());
|
||||
assertTrue("Should be a RuntimeException", errors.get(0).getError() instanceof RuntimeException);
|
||||
assertThat(errors, hasSize(1));
|
||||
ProcessingError error = errors.get(0);
|
||||
assertThat(error.getMsg(), containsString("java.lang.UnsupportedOperationException: Test exception while applying rule\n"));
|
||||
assertThat(error.getMsg(), containsString("Rule applied on node=Foo"));
|
||||
assertThat(error.getError().getCause(), instanceOf(UnsupportedOperationException.class));
|
||||
|
||||
assertEquals("There should be a violation", 1, context.getReport().getViolations().size());
|
||||
assertThat(context.getReport().getViolations(), hasSize(1));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -4,6 +4,10 @@
|
||||
|
||||
package net.sourceforge.pmd;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -14,7 +18,9 @@ import org.junit.Test;
|
||||
import org.junit.contrib.java.lang.system.RestoreSystemProperties;
|
||||
import org.junit.rules.TestRule;
|
||||
|
||||
import net.sourceforge.pmd.Report.ProcessingError;
|
||||
import net.sourceforge.pmd.internal.SystemProps;
|
||||
import net.sourceforge.pmd.internal.util.ContextedAssertionError;
|
||||
import net.sourceforge.pmd.lang.DummyLanguageModule;
|
||||
import net.sourceforge.pmd.lang.Language;
|
||||
import net.sourceforge.pmd.lang.LanguageRegistry;
|
||||
@@ -65,8 +71,9 @@ public class SourceCodeProcessorTest {
|
||||
ctx.setLanguageVersion(dummyDefault);
|
||||
|
||||
processor.processSourceCode(sourceCode, new RuleSets(rulesets), ctx);
|
||||
Assert.assertEquals(1, ctx.getReport().getProcessingErrors().size());
|
||||
Assert.assertSame(AssertionError.class, ctx.getReport().getProcessingErrors().get(0).getError().getClass());
|
||||
List<ProcessingError> errors = ctx.getReport().getProcessingErrors();
|
||||
assertThat(errors, hasSize(1));
|
||||
assertThat(errors.get(0).getError(), instanceOf(ContextedAssertionError.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in new issue
Block a user