You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 55 Next »

Methods are forbidden to throw RuntimeException or Exception. Handling these exceptions requires catching RuntimeException, which is forbidden in guideline ERR14-J. Catch specific exceptions rather than the more general RuntimeException or Exception. Moreover, throwing a RuntimeException can lead to subtle errors, for instance, a caller cannot examine the exception to determine why it was thrown, and consequently cannot attempt recovery.

Instead, throw a more specific exception, subclassed from Exception. Note that it is permissible to construct an exception class specifically for a single throw statement.

Noncompliant Code Example

This noncompliant code example accepts a string and returns true when it consists of a capital letter followed by lowercase letters. To handle corner cases, it checks for various exceptional conditions and throws exceptions when they are likely to disrupt normal operation.

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 properly handle the case of passing in a null string parameter, any code that calls this method must catch RuntimeException, which violates guideline ERR14-J. Catch specific exceptions rather than the more general RuntimeException or Exception.

Compliant Solution

This compliant solution throws a specific exception (NullPointerException) to denote the particular exceptional condition.

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

Actually the null check is redundant, if the null check were removed, then the next call (s.equals("")) would throw a NullPointerException if s was null. However, the explicit null check is good form, as it explicitly signifies the code's intention. More complex code may require explicit testing of invariants and appropriate throw statements.

Noncompliant Code Example

This noncompliant code example 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 while continuing to respect the required abstraction level.

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

Using instanceof to check for narrower exceptions in a general catch block is often insufficient; it is usually impossible to enumerate all possible exceptions that the code could throw.

Exceptions

EXC13-EX0: Classes that sanitize exceptions to comply with a security policy are permitted to translate specific exceptions into more general exceptions. This translation could potentially result in throwing RuntimeException or Exception in some cases, depending on the details of the security policy.

Risk Assessment

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

Guideline

Severity

Likelihood

Remediation Cost

Priority

Level

EXC13-J

low

likely

medium

P6

L2

Related Vulnerabilities

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

Bibliography

[[Goetz 2004b]]
[[MITRE 2009]] CWE ID 397 "Declaration of Throws for Generic Exception", CWE ID 537 "Information Leak Through Java Runtime Error Message"
[[Tutorials 2008]] Unchecked Exceptions — The Controversy


ERR12-J. Do not log unsanitized user input      06. Exceptional Behavior (ERR)      ERR14-J. Catch specific exceptions rather than the more general RuntimeException or Exception

  • No labels