Wednesday, September 28, 2011

PMD - Strict Exception Rules

The sixteenth installment of explanation of PMD rules covering Strict Exception Rules

Strict Exception Rules

These rules provide some strict guidelines about throwing and catching exceptions.

AvoidCatchingThrowable

This is dangerous because it casts too wide a net; it can catch things like OutOfMemoryError.

Example

public class Foo {
public void bar() {
  try {
   // do something
  } catch (Throwable th) {  //Should not catch throwable
   th.printStackTrace();
  }
}
}

SignatureDeclareThrowsException

It is unclear which exceptions that can be thrown from the methods. It might be difficult to document and understand the vague interfaces. Use either a class derived from RuntimeException or a checked exception.

Example

public void methodThrowingException() throws Exception {
}

ExceptionAsFlowControl

Using Exceptions as flow control leads to GOTOish code and obscures true exceptions when debugging.

Example

public class Foo {
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
  }
}
}

AvoidCatchingNPE

Code should never throw NPE under normal circumstances. A catch block may hide the original error, causing other more subtle errors in its wake.

Example

public class Foo {
void bar() {
  try {
   // do something
   }  catch (NullPointerException npe) {
  }
}
}

AvoidThrowingRawExceptionTypes

Avoid throwing certain exception types. Rather than throw a raw RuntimeException, Throwable, Exception, or Error, use a subclassed exception or error instead.

Example

public class Foo {
public void bar() throws Exception {
  throw new Exception();
}
}

AvoidThrowingNullPointerException

Avoid throwing a NullPointerException - it's 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.

Example

public class Foo {
void bar() {
  throw new NullPointerException();
}
}

AvoidRethrowingException

Catch blocks that merely rethrow a caught exception only add to code size and runtime complexity.

Example

public class Foo {
   void bar() {
    try {
    // do something
    }  catch (SomeException se) {
       throw se;
    }
   }
  }

DoNotExtendJavaLangError

Errors are system exceptions. Do not extend them.

Example

public class Foo extends Error { }

DoNotThrowExceptionInFinally

Throwing exception in a finally block is confusing. It may mask exception or a defect of the code, it also render code cleanup uninstable. Note: This is a PMD implementation of the Lint4j rule "A throw in a finally block"

Example

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();
               }
        }
}

AvoidThrowingNewInstanceOfSameException

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.

Example

public class Foo {
     void bar() {
      try {
       // do something
      }  catch (SomeException se) {
         // harmless comment      
           throw new SomeException(se);
      }
     }
    }

No comments: