new rule in strictexception: AvoidThrowingNewInstanceOfSameException

contributed by George Thomas:

https://sourceforge.net/tracker/?func=detail&atid=479923&aid=2566369&group_id=56262


git-svn-id: https://pmd.svn.sourceforge.net/svnroot/pmd/branches/pmd/4.2.x@6814 51baf565-9d33-0410-a72c-fc3788e3496d
This commit is contained in:
Xavier Le Vourch 2009-02-05 03:29:15 +00:00
parent b5a90924a7
commit 751ed84e0d
4 changed files with 185 additions and 1 deletions

View File

@ -10,6 +10,9 @@ Fixed bug 2404700 - UseSingleton should not act on enums
Fixed bug 2225474 - VariableNamingConventions does not work with nonprimitives
Fixed bug - JUnitTestsShouldIncludeAssert now detects Junit 4 Assert.assert... constructs
New rule:
StrictExceptions : AvoidThrowingNewInstanceOfSameException
October 12, 2008 - 4.2.4:
Fixed bug 1481051 - false + UnusedNullCheckInEquals (and other false positives too)

View File

@ -11,6 +11,7 @@ public class StrictExceptionRulesTest extends SimpleAggregatorTst {
addRule("strictexception", "AvoidCatchingNPE");
addRule("strictexception", "AvoidCatchingThrowable");
addRule("strictexception", "AvoidRethrowingException");
addRule("strictexception", "AvoidThrowingNewInstanceOfSameException");
addRule("strictexception", "AvoidThrowingNullPointerException");
addRule("strictexception", "AvoidThrowingRawExceptionTypes");
addRule("strictexception", "DoNotExtendJavaLangError");

View File

@ -0,0 +1,139 @@
<?xml version="1.0" encoding="UTF-8"?>
<test-data>
<test-code>
<description><![CDATA[
basic failure case
]]></description>
<expected-problems>1</expected-problems>
<code><![CDATA[
public class Foo {
void bar() {
try {
} catch (SomeException se) {
throw new SomeException(se);
}
}
}
]]></code>
</test-code>
<test-code>
<description><![CDATA[
do something else before throwing a new instance of the same exception, ok
]]></description>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class Foo {
void bar() {
try {
} catch (SomeException se) {
System.out.println("something interesting");
throw new SomeException(se);
}
}
}
]]></code>
</test-code>
<test-code>
<description><![CDATA[
repackage cause as an instance of the same exception, failure
]]></description>
<expected-problems>1</expected-problems>
<code><![CDATA[
public class Foo {
void bar() {
try {
} catch (SomeException se) {
throw new SomeException(se.getCause());
}
}
}
]]></code>
</test-code>
<test-code>
<description><![CDATA[
throw new instance of the same exception with a different message, ok
]]></description>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class Foo {
void bar() {
try {
} catch (SomeException se) {
throw new SomeException("new exception message", se);
}
}
}
]]></code>
</test-code>
<test-code>
<description><![CDATA[
throw new instance of the same exception with the same message, failure
]]></description>
<expected-problems>1</expected-problems>
<code><![CDATA[
public class Foo {
void bar() {
try {
} catch (SomeException se) {
throw new SomeException(se.getMessage());
}
}
}
]]></code>
</test-code>
<test-code>
<description><![CDATA[
throws a new instance of the same exception without any arguments, ok
]]></description>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class Foo {
void bar() {
try {
} catch (SomeException se) {
throw new SomeException();
}
}
}
]]></code>
</test-code>
<test-code>
<description><![CDATA[
throws a new instance of the same exception from a nested try/catch block, ok
]]></description>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class Foo {
void bar() {
try {
} catch (SomeException se) {
try {
} catch (OtherException oe) {
throw new SomeException();
}
}
}
}
]]></code>
</test-code>
<test-code>
<description><![CDATA[
wraps the exception in a new instance of the same exception from a nested try/catch block, ok
]]></description>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class Foo {
void bar() {
try {
} catch (SomeException se) {
try {
} catch (OtherException oe) {
throw new SomeException(se);
}
}
}
}
]]></code>
</test-code>
</test-data>

View File

@ -287,7 +287,48 @@ public class Foo {
}
]]>
</example>
</rule>
</rule>
<rule name="AvoidThrowingNewInstanceOfSameException"
since="4.2.5"
message="A catch statement that catches an exception only to wrap it in a new instance of the same type of exception and throw it should be avoided"
externalInfoUrl="http://pmd.sourceforge.net/rules/strictexception.html#AvoidThrowingNewInstanceOfSameException"
class="net.sourceforge.pmd.rules.XPathRule">
<description>
Catch blocks that merely rethrow a caught exception wrapped inside a new instance of the same type only add to code size and runtime complexity.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//CatchStatement[
count(Block/BlockStatement/Statement) = 1
and
FormalParameter/Type/ReferenceType/ClassOrInterfaceType/@Image = Block/BlockStatement/Statement/ThrowStatement/Expression/PrimaryExpression/PrimaryPrefix/AllocationExpression/ClassOrInterfaceType/@Image
and
count(Block/BlockStatement/Statement/ThrowStatement/Expression/PrimaryExpression/PrimaryPrefix/AllocationExpression/Arguments/ArgumentList/Expression) = 1
and
FormalParameter/VariableDeclaratorId = Block/BlockStatement/Statement/ThrowStatement/Expression/PrimaryExpression/PrimaryPrefix/AllocationExpression/Arguments/ArgumentList/Expression/PrimaryExpression/PrimaryPrefix/Name
]
]]>
</value>
</property>
</properties>
<example> <![CDATA[
public class Foo {
void bar() {
try {
// do something
} catch (SomeException se) {
// harmless comment
throw new SomeException(se);
}
}
}
]]>
</example>
</rule>
</ruleset>