<?xml version="1.0"?>

<ruleset name="Strict Exceptions"
    xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
  <description>
These rules provide some strict guidelines about throwing and catching exceptions.
  </description>

   <rule name="AvoidCatchingThrowable"
   		since="1.2"
         message="A catch statement should never catch throwable since it includes errors."
          class="net.sourceforge.pmd.lang.java.rule.strictexception.AvoidCatchingThrowableRule"
          externalInfoUrl="${pmd.website.baseurl}/rules/java/strictexception.html#AvoidCatchingThrowable">
      <description>
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.
      </description>
      <priority>3</priority>
      <example>
	<![CDATA[
public void bar() {
	try {
     // do something
    } catch (Throwable th) {  // should not catch Throwable
		th.printStackTrace();
    }
  }
	]]>
      </example>
    </rule>

   <rule name="SignatureDeclareThrowsException"
   		since="1.2"
         message="A method/constructor shouldn't explicitly throw java.lang.Exception"
          class="net.sourceforge.pmd.lang.java.rule.strictexception.SignatureDeclareThrowsExceptionRule"
          externalInfoUrl="${pmd.website.baseurl}/rules/java/strictexception.html#SignatureDeclareThrowsException">
      <description>
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.
      </description>
      <priority>3</priority>
      <example>
                <![CDATA[
public void foo() throws Exception {
}
                ]]>
      </example>
    </rule>

    <rule name="ExceptionAsFlowControl"
    		 since="1.8"
          message="Avoid using exceptions as flow control."
          class="net.sourceforge.pmd.lang.java.rule.strictexception.ExceptionAsFlowControlRule"
          externalInfoUrl="${pmd.website.baseurl}/rules/java/strictexception.html#ExceptionAsFlowControl">
      <description>
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.
      </description>
        <priority>3</priority>
      <example>
  <![CDATA[
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
    }
  }
  ]]>
      </example>
    </rule>

<rule name="AvoidCatchingNPE"
   		language="java"
	 since="1.8"
    message="Avoid catching NullPointerException; consider removing the cause of the NPE."
    class="net.sourceforge.pmd.lang.rule.XPathRule"
          externalInfoUrl="${pmd.website.baseurl}/rules/java/strictexception.html#AvoidCatchingNPE">
    <description>
Code should never throw NullPointerExceptions under normal circumstances.  A catch block may hide the 
original error, causing other, more subtle problems later on.
    </description>
    <priority>3</priority>
    <properties>
      <property name="xpath">
        <value>
            <![CDATA[
//CatchStatement/FormalParameter/Type
 /ReferenceType/ClassOrInterfaceType[@Image='NullPointerException']
 ]]>
        </value>
      </property>
    </properties>
    <example>  <![CDATA[
public class Foo {
  void bar() {
    try {
      // do something
      }  catch (NullPointerException npe) {
    }
  }
}
]]>
    </example>
  </rule>

  <rule name="AvoidThrowingRawExceptionTypes"
   		language="java"
      since="1.8"
      message="Avoid throwing raw exception types."
      class="net.sourceforge.pmd.lang.rule.XPathRule"
          externalInfoUrl="${pmd.website.baseurl}/rules/java/strictexception.html#AvoidThrowingRawExceptionTypes">
    <description>
Avoid throwing certain exception types. Rather than throw a raw RuntimeException, Throwable,
Exception, or Error, use a subclassed exception or error instead.
    </description>
    <priority>1</priority>
    <properties>
      <property name="xpath">
        <value>
            <![CDATA[
//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)
]
 ]]>
        </value>
      </property>
    </properties>
    <example>
      <![CDATA[
public class Foo {
  public void bar() throws Exception {
    throw new Exception();
   }
}
]]>
    </example>
  </rule>

    <rule name="AvoidThrowingNullPointerException"
   		language="java"
    	  since="1.8"
        message="Avoid throwing null pointer exceptions."
        class="net.sourceforge.pmd.lang.rule.XPathRule"
          externalInfoUrl="${pmd.website.baseurl}/rules/java/strictexception.html#AvoidThrowingNullPointerException">
      <description>
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.
      </description>
      <priority>1</priority>
      <properties>
        <property name="xpath">
          <value>
              <![CDATA[
//AllocationExpression/ClassOrInterfaceType[@Image='NullPointerException']
   ]]>
          </value>
        </property>
      </properties>
      <example>
        <![CDATA[
public class Foo {
  void bar() {
    throw new NullPointerException();
  }
}
  ]]>
      </example>
    </rule>

  <rule name="AvoidRethrowingException"
   		language="java"
    since="3.8"
    message="A catch statement that catches an exception only to rethrow it should be avoided."
    class="net.sourceforge.pmd.lang.rule.XPathRule"
    externalInfoUrl="${pmd.website.baseurl}/rules/java/strictexception.html#AvoidRethrowingException">
    <description>
Catch blocks that merely rethrow a caught exception only add to code size and runtime complexity.
    </description>
    <priority>3</priority>
    <properties>
        <property name="xpath">
            <value>
                <![CDATA[
//CatchStatement[FormalParameter
 /VariableDeclaratorId/@Image = Block/BlockStatement/Statement
 /ThrowStatement/Expression/PrimaryExpression[count(PrimarySuffix)=0]/PrimaryPrefix/Name/@Image
 and count(Block/BlockStatement/Statement) =1]
 ]]>
            </value>
        </property>
    </properties>
    <example>  <![CDATA[
public void bar() {
    try {
    // do something
    }  catch (SomeException se) {
       throw se;
    }
}
  ]]>
    </example>
  </rule>

  <rule
    name="DoNotExtendJavaLangError"
   		language="java"
    since="4.0"
    message="Exceptions should not extend java.lang.Error"
    class="net.sourceforge.pmd.lang.rule.XPathRule"
    externalInfoUrl="${pmd.website.baseurl}/rules/java/strictexception.html#DoNotExtendJavaLangError">
    <description>
      <![CDATA[
Errors are system exceptions. Do not extend them.
      ]]>
    </description>
    <priority>3</priority>
    <properties>
      <property name="xpath">
        <value>
          <![CDATA[
//ClassOrInterfaceDeclaration/ExtendsList/ClassOrInterfaceType
  [@Image="Error" or @Image="java.lang.Error"]
          ]]>
        </value>
      </property>
    </properties>
    <example><![CDATA[
public class Foo extends Error { }
    ]]></example>
  </rule>

	<rule	name="DoNotThrowExceptionInFinally"
   		language="java"
	       since="4.2"
		    message="A throw statement in a finally block makes the control flow hard to understand."
		    class="net.sourceforge.pmd.lang.rule.XPathRule"
		    externalInfoUrl="${pmd.website.baseurl}/rules/java/strictexception.html#DoNotThrowExceptionInFinally">
    	<description>
			<![CDATA[
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"
			]]>
		</description>
    	<priority>4</priority>
    	<properties>
			<property name="xpath">
			  <value>
			    <![CDATA[
//FinallyStatement[descendant::ThrowStatement]
			          ]]>
			  </value>
			</property>
		</properties>
    	<example>
    		<![CDATA[
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();
		}
	}
}
	    	]]>
    	</example>
    </rule>

  <rule name="AvoidThrowingNewInstanceOfSameException"
    since="4.2.5" language="java"
    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="${pmd.website.baseurl}/rules/java/strictexception.html#AvoidThrowingNewInstanceOfSameException"
    class="net.sourceforge.pmd.lang.rule.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 void bar() {
      try {
       // do something
      }  catch (SomeException se) {
         // harmless comment      
           throw new SomeException(se);
      }
}
  ]]>
    </example>
  </rule>

  <rule  name="AvoidCatchingGenericException"
    since="4.2.6" language="java"
    message="Avoid catching generic exceptions such as NullPointerException, RuntimeException, Exception in try-catch block"
    externalInfoUrl="${pmd.website.baseurl}/rules/java/strictexception.html#AvoidCatchingGenericException"
    class="net.sourceforge.pmd.lang.rule.XPathRule">
    <description>
Avoid catching generic exceptions such as NullPointerException, RuntimeException, Exception in try-catch block
    </description>
    <priority>3</priority>
    <properties>
      <property name="xpath">
      <value>
      <![CDATA[
        //CatchStatement/FormalParameter/Type/ReferenceType/ClassOrInterfaceType[
          @Image='NullPointerException' or
          @Image='Exception' or
          @Image='RuntimeException']
      ]]>
      </value>
      </property>
    </properties>
    <example>
    <![CDATA[
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();
    }
  } 
}
    ]]>
    </example>
  </rule>

	<rule name="AvoidLosingExceptionInformation"
		since="4.2.6" language="java"
		message="Avoid statements in a catch block that invoke accessors on the exception without using the information"
		externalInfoUrl="${pmd.website.baseurl}/rules/java/strictexception.html#AvoidLosingExceptionInformation"
		class="net.sourceforge.pmd.lang.rule.XPathRule">
		<description>
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.
		</description>
		<priority>2</priority>
		<properties>
			<property name="xpath">
				<value>
<![CDATA[
//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')
]
]]>
				</value>
			</property>
		</properties>
		<example>
<![CDATA[
public void bar() {
	try {
		// do something
	} catch (SomeException se) {
		se.getMessage();
	}
}
]]>
		</example>
	</rule>

</ruleset>