Programmers often fall into the trap of suppressing or ignoring checked exceptions. Unless there is a valid reason for ignoring exceptions, such as the client cannot be expected to stage a recovery, it is important to handle them appropriately.
Catching and suppressing exceptions is considered bad practice for several reasons. Exceptions disrupt the expected control flow of the application. For example, statements that occur in the try
block after the statement that caused the exception, do not execute as required.
To ensure that the program does not resume with invalid invariants, the catch
block should immediately stop control flow from proceeding, instead of ignoring or suppressing the exception. If the program is capable of recovering from the exceptional condition, the statements in the try
block that are required to be executed, must be moved outside the try
block.
Noncompliant Code Example
This noncompliant code example adorns the catch
block with an ignore comment and forgoes appropriate exception handling.
Code Block | ||
---|---|---|
| ||
try { //... } catch(IOException ioe) { // Ignore } |
Noncompliant Code Example
Printing the exception's stack trace can be useful for debugging purposes but is equivalent to ignoring the exception, as this noncompliant code example demonstrates.
Code Block | ||
---|---|---|
| ||
try { //... } catch(IOException ioe) { ioe.printStacktrace(); } |
Note that even though the application reacts to the exception by printing out a stack trace, it proceeds as if the exception was not thrown, that is, the future long term behavior of the application does not change based on the throwing of the exception, other than the fact that impending statements in the try block are skipped. Given that the resulting IOException
indicates that an operation attempted by the application failed, it is unlikely that the application will be able to operate successfully by assuming that the attempted operation succeeded.
Compliant Solution
This compliant solution attempts to recover from a FileNotFoundException
by forcing the user to specify another file when a particular file does not exist in the user-specific directory.
Code Block | ||
---|---|---|
| ||
boolean volatile validFlag = false; do { try { // If requested file does not exist, throws FileNotFoundException // If requested file exists, sets a Boolean flag validFlag to true validFlag = true; } catch(FileNotFoundException e) { // Ask the user for a different filename } } while(validFlag != true); // Use the file |
The user is allowed to access files in only the user-specific directory so no file system information is leaked in the process (EXC06-J. Do not allow exceptions to transmit sensitive information).
Noncompliant Code Example
It is not possible to propagate a checked exception by throwing it from a Runnable
object's run()
method. Consequently, this noncompliant code example catches java.lang.InterruptedException
but ignores it.
Code Block | ||
---|---|---|
| ||
class Foo implements Runnable { public void run() { try { Thread.sleep(1000); } catch(InterruptedException e) { // Ignore } } } |
Wiki Markup |
---|
Any callers higher up in the call stack are unable to determine that an interrupted exception occurred and act on it \[[Goetz 2006|AA. Java References#Goetz 06]\]. |
Compliant Solution
This compliant solution catches the InterruptedException
and restores the interrupted status by calling the interrupt()
method on the current thread.
Code Block | ||
---|---|---|
| ||
class Foo implements Runnable { public void run() { try { Thread.sleep(1000); } catch(InterruptedException e) { Thread.currentThread().interrupt(); // Reset interrupted status } } } |
Wiki Markup |
---|
Consequently, code that is higher up on the call stack can see that an interrupt was issued \[[Goetz 2006|AA. Java References#Goetz 06]\]. |
Exceptions
EX1: It is reasonable to ignore handling an exception that occurs within a catch
or finally
block, such as when closing a FileInputStream
object.
EX2: It is also permissible to ignore handling an exception when it is not possible to recover from the exceptional condition at that abstraction level. In such cases, the exception must be thrown so that higher level code can try recovering from the exceptional condition by catching and handling it.
Code Block | ||
---|---|---|
| ||
// When recovery is possible at higher levels private void doSomething() throws FileNotFoundException { // Requested file does not exist; throws FileNotFoundException // Higher level code can handle it by displaying a dialog box and asking // the user for the file name } |
If the higher level code is also incapable of staging a recovery, the checked exception may be wrapped in an unchecked exception and re-thrown.
Code Block | ||
---|---|---|
| ||
try { // Requested file does not exist // User is unable to supply the file name } catch(FileNotFoundException e) { throw new RuntimeException(e); } |
Wiki Markup |
---|
*EX3:* "The only situation in which it is acceptable to swallow an interrupt is when you are extending Thread and therefore control all the code higher up on the call stack." \[[Goetz 2006|AA. Java References#Goetz 06]\]. In such cases {{InterruptedException}} may be caught and ignored. A interruption request may also be swallowed by code that implements a thread's interruption policy \[[Goetz 2006, pg 143|AA. Java References#Goetz 06]\]. |
Risk Assessment
Ignoring or suppressing exceptions violates the fail-safe criteria of an application.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
EXC00- J | low | probable | medium | P4 | L3 |
Automated Detection
TODO
Related Vulnerabilities
References
Wiki Markup |
---|
\[[JLS 2005|AA. Java References#JLS 05]\] [Chapter 11, Exceptions|http://java.sun.com/docs/books/jls/third_edition/html/exceptions.html] \[[Bloch 2008|AA. Java References#Bloch 08]\] Item 65: "Don't ignore exceptions", Item 62: "Document all exceptions thrown by each method" \[[Goetz 2006|AA. Java References#Goetz 06]\] 5.4 Blocking and interruptible methods \[[MITRE 2009|AA. Java References#MITRE 09]\] [CWE ID 390|http://cwe.mitre.org/data/definitions/390.html] "Detection of Error Condition Without Action" |
17. Exceptional Behavior (EXC) 17. Exceptional Behavior (EXC) EXC01-J. Use a class dedicated to reporting exceptions