These rules provide some strict guidelines about throwing and catching exceptions.
Since: PMD 1.2
Priority: 3
Catching Throwable errors is not recommended since its scope is very broad. It includes runtime issues such as OutOfMemoryError that should be exposed and managed separately.
This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.strictexception.AvoidCatchingThrowableRule
Example(s):
public void bar() { try { // do something } catch (Throwable th) { // should not catch Throwable th.printStackTrace(); } }
This rule has the following properties:
Name | Default Value | Description |
---|---|---|
violationSuppressRegex | Suppress violations with messages matching a regular expression | |
violationSuppressXPath | Suppress violations on nodes which match a given relative XPath expression. |
Since: PMD 1.2
Priority: 3
Methods that declare the generic Exception as a possible throwable are not very helpful since their failure modes are unclear. Use a class derived from RuntimeException or a more specific checked exception.
This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.strictexception.SignatureDeclareThrowsExceptionRule
Example(s):
public void foo() throws Exception { }
This rule has the following properties:
Name | Default Value | Description |
---|---|---|
violationSuppressRegex | Suppress violations with messages matching a regular expression | |
violationSuppressXPath | Suppress violations on nodes which match a given relative XPath expression. |
Since: PMD 1.8
Priority: 3
Using Exceptions as form of flow control is not recommended as they obscure true exceptions when debugging. Either add the necessary validation or use an alternate control structure.
This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.strictexception.ExceptionAsFlowControlRule
Example(s):
public void bar() { try { try { } catch (Exception e) { throw new WrapperException(e); // this is essentially a GOTO to the WrapperException catch block } } catch (WrapperException e) { // do some more stuff } }
This rule has the following properties:
Name | Default Value | Description |
---|---|---|
violationSuppressRegex | Suppress violations with messages matching a regular expression | |
violationSuppressXPath | Suppress violations on nodes which match a given relative XPath expression. |
Since: PMD 1.8
Priority: 3
Code should never throw NullPointerExceptions under normal circumstances. A catch block may hide the original error, causing other, more subtle problems later on.
//CatchStatement/FormalParameter/Type /ReferenceType/ClassOrInterfaceType[@Image='NullPointerException']
Example(s):
public class Foo { void bar() { try { // do something } catch (NullPointerException npe) { } } }
Since: PMD 1.8
Priority: 1
Avoid throwing certain exception types. Rather than throw a raw RuntimeException, Throwable, Exception, or Error, use a subclassed exception or error instead.
//ThrowStatement//AllocationExpression /ClassOrInterfaceType[ (@Image='Throwable' and count(//ImportDeclaration/Name[ends-with(@Image,'Throwable')]) = 0) or (@Image='Exception' and count(//ImportDeclaration/Name[ends-with(@Image,'Exception')]) = 0) or (@Image='Error' and count(//ImportDeclaration/Name[ends-with(@Image,'Error')]) = 0) or ( @Image='RuntimeException' and count(//ImportDeclaration/Name[ends-with(@Image,'RuntimeException')]) = 0) ]
Example(s):
public class Foo { public void bar() throws Exception { throw new Exception(); } }
Since: PMD 1.8
Priority: 1
Avoid throwing NullPointerExceptions. These are confusing because most people will assume that the virtual machine threw it. Consider using an IllegalArgumentException instead; this will be clearly seen as a programmer-initiated exception.
//AllocationExpression/ClassOrInterfaceType[@Image='NullPointerException']
Example(s):
public class Foo { void bar() { throw new NullPointerException(); } }
Since: PMD 3.8
Priority: 3
Catch blocks that merely rethrow a caught exception only add to code size and runtime complexity.
//CatchStatement[FormalParameter /VariableDeclaratorId/@Image = Block/BlockStatement/Statement /ThrowStatement/Expression/PrimaryExpression[count(PrimarySuffix)=0]/PrimaryPrefix/Name/@Image and count(Block/BlockStatement/Statement) =1]
Example(s):
public void bar() { try { // do something } catch (SomeException se) { throw se; } }
Since: PMD 4.0
Priority: 3
Errors are system exceptions. Do not extend them.
//ClassOrInterfaceDeclaration/ExtendsList/ClassOrInterfaceType [@Image="Error" or @Image="java.lang.Error"]
Example(s):
public class Foo extends Error { }
Since: PMD 4.2
Priority: 4
Throwing exceptions within a ‘finally’ block is confusing since they may mask other exceptions or code defects. Note: This is a PMD implementation of the Lint4j rule “A throw in a finally block”
//FinallyStatement[descendant::ThrowStatement]
Example(s):
public class Foo { public void bar() { try { // Here do some stuff } catch( Exception e) { // Handling the issue } finally { // is this really a good idea ? throw new Exception(); } } }
Since: PMD 4.2.5
Priority: 3
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.
//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 ]
Example(s):
public void bar() { try { // do something } catch (SomeException se) { // harmless comment throw new SomeException(se); } }
Since: PMD 4.2.6
Priority: 3
Avoid catching generic exceptions such as NullPointerException, RuntimeException, Exception in try-catch block
//CatchStatement/FormalParameter/Type/ReferenceType/ClassOrInterfaceType[ @Image='NullPointerException' or @Image='Exception' or @Image='RuntimeException']
Example(s):
package com.igate.primitive; public class PrimitiveType { public void downCastPrimitiveType() { try { System.out.println(" i [" + i + "]"); } catch(Exception e) { e.printStackTrace(); } catch(RuntimeException e) { e.printStackTrace(); } catch(NullPointerException e) { e.printStackTrace(); } } }
Since: PMD 4.2.6
Priority: 2
Statements in a catch block that invoke accessors on the exception without using the information only add to code size. Either remove the invocation, or use the return result.
//CatchStatement/Block/BlockStatement/Statement/StatementExpression/PrimaryExpression/PrimaryPrefix/Name [ @Image = concat(../../../../../../../FormalParameter/VariableDeclaratorId/@Image, '.getMessage') or @Image = concat(../../../../../../../FormalParameter/VariableDeclaratorId/@Image, '.getLocalizedMessage') or @Image = concat(../../../../../../../FormalParameter/VariableDeclaratorId/@Image, '.getCause') or @Image = concat(../../../../../../../FormalParameter/VariableDeclaratorId/@Image, '.getStackTrace') or @Image = concat(../../../../../../../FormalParameter/VariableDeclaratorId/@Image, '.toString') ]
Example(s):
public void bar() { try { // do something } catch (SomeException se) { se.getMessage(); } }