Methods are forbidden to throw RuntimeException
or Exception
; handling these exceptions requires catching RuntimeException
, which is forbidden in guideline EXC14-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, prefer throwing 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 handle the case of passing in a null
string parameter, code calling this method may require catching RuntimeException
, which is a violation of guideline EXC14-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) { // redundant; shown for clarity throw new NullPointerException();// redundant; shown for clarity } // redundant; shown for clarity 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())); }
Although the explicit throw statement is redundant in this small example, 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.
EXC13-EX1: Widely used pre-existing APIs whose previous versions contain methods that throw RuntimeException
or Exception
may continue to do so, to preserve backwards compatibility. We strongly encourage maintainers of such APIs to consider deprecating such methods, replacing them with methods that throw more specific exceptions.
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
EXC12-J. Do not log unsanitized user input 06. Exceptional Behavior (EXC) EXC14-J. Catch specific exceptions rather than the more general RuntimeException or Exception