A method should never throw {{RuntimeException}} or {{Exception}}. This is because handling these requires catching {{RuntimeException}}, which is forbidden in [EXC32-J. Catch specific exceptions as opposed to the more general RuntimeException]. Moreover, throwing a {{RuntimeException}} can lead to subtle errors such as a caller who fails to retrieve a return value from an offending method, is unable to check for appropriate feedback. The Java Language Specification (Section 8.4.7 Method Body) allows the declaration of a method with a return type without making it necessary to return a value if a runtime exception is thrown from within the method \[[JLS 05|AA. Java References#JLS 05]\].

Instead, always throw an exception subclassed from Exception. It is permissible to construct an exception class specifically for a single throw statement.

Noncompliant Code Example

The following function takes a string and returns true if it consists of a capital letter followed by lowercase letters. To handle corner cases, it checks for the conditions and throws exceptions if they are likely to prevent normal analysis.

boolean isCapitalized(String s) {
  if (s == null) {
    throw new RuntimeException("Null String");
  }
  if (s.equals("")) {
    return true;
  }
  String first = s.substring( 0, 1);
  String rest = s.substring( 1);
  return (first.equals( first.toUpperCase()) &&
          rest.equals( rest.toLowerCase()));
}

To handle the case of passing in a null string parameter, code calling this function may require catching RuntimeException, which is a violation of EXC32-J. Catch specific exceptions as opposed to the more general RuntimeException.

Compliant Solution

An exception specifically devoted to the error is more appropriate.

boolean isCapitalized(String s) {
  if (s == null) {
    throw new NullPointerException();
  }
  if (s.equals("")) {
    return true;
  }
  String first = s.substring( 0, 1);
  String rest = s.substring( 1);
  return (first.equals( first.toUpperCase()) &&
          rest.equals( rest.toLowerCase()));
}

Noncompliant Code Example

This noncompliant code snippet uses a broad Exception class in the throws declaration of the method.

private void doSomething() throws Exception {
//...
}

Compliant Solution

To be compliant, be as specific as possible when declaring exceptions and respect the required abstraction level.

private void doSomething() throws IOException {
//...
}

Risk Assessment

Throwing RuntimeException, Exception prevents classes from catching the intended exception without catching other unintended exceptions as well.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

EXC33- J

low

likely

medium

P6

L2

Automated Detection

TODO

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

References

\[[MITRE 09|AA. Java References#MITRE 09]\] [CWE ID 397|http://cwe.mitre.org/data/definitions/397.html] "Declaration of Throws for Generic Exception", [CWE ID 537|http://cwe.mitre.org/data/definitions/537.html] "Information Leak Through Java Runtime Error Message"
\[[Goetz 04b|AA. Java References#Goetz 04b]\]
\[[Tutorials 08|AA. Java References#Tutorials 08]\] [Unchecked Exceptions — The Controversy|http://java.sun.com/docs/books/tutorial/essential/exceptions/runtime.html]


EXC32-J. Catch specific exceptions as opposed to the more general RuntimeException      13. Exceptional Behavior (EXC)      13. Serialization (SER)