| Wiki Markup |
|---|
A method should never throw {{RuntimeException}} or {{Exception}}. This is because handling these requires catching {{RuntimeException}}, which is forbidden in [EXC32-J. Do not catch RuntimeException]. Moreover, throwing a {{RuntimeException}} can lead to subtle errors such as a caller who fails to retrieve a return value from the 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 succeeded by lowercase letters. To handle corner cases, it checks for them and throws exceptions if they would prevent normal analysis.
| Code Block | ||
|---|---|---|
| ||
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()));
}
|
In order to handle the case of passing in a null string, code calling this function would have to catch RuntimeException, which violates EXC32-J. Do not catch RuntimeException
Compliant Solution
An exception specifically devoted to the error would be more appropriate.
| Code Block | ||
|---|---|---|
| ||
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 statement within the method declaration.
| Code Block | ||
|---|---|---|
| ||
private void doSomething() throws Exception {
//...
}
|
Compliant Solution
To be compliant, be as specific as possible while declaring exceptions and heed the given abstraction level.
| Code Block | ||
|---|---|---|
| ||
private void doSomething() throws IOException {
//...
}
|
Risk Assessment
Throwing RuntimeException, Exception, or General prevents classes from catching your 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
| Wiki Markup |
|---|
\[[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] |
EXC03-J. Try to recover gracefully from system errors 11. Exceptional Behavior (EXC) EXC30-J. Do not exit abruptly from a finally block