Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

This noncompliant code example simply prints the exception's stack trace.

Code Block
bgColor#FFCCCC

try {
  //...
} catch (IOException ioe) {
  ioe.printStackTrace();
}

...

This compliant solution handles a FileNotFoundException by requesting that the user specify another file name.

Code Block
bgColor#ccccff

volatile boolean validFlag = false;
do {
  try {
    // If requested file does not exist, throws FileNotFoundException
    // If requested file exists, sets validFlag to true
    validFlag = true;
  } catch (FileNotFoundException e) {
    // Ask the user for a different file name
  }
} while (validFlag != true);
// Use the file

...

Proper reporting of exceptional conditions is context-dependent. For example, GUI applications should report the exception in a graphical manner, such as in an error dialog box. Most library classes should be able to objectively determine how an exception should be reported to preserve modularity; they cannot rely on System.err, on any particular logger, or on the availability of the windowing environment. As a result, library classes that wish to report exceptions should specify the API they use to report exceptions. This compliant solution specifies both an interface for reporting exceptions, which exports the report() method, and a default exception reporter class that the library can use. The exception reporter can be overridden by subclasses.

Code Block
bgColor#ccccff

public interface Reporter {
  public void report(Throwable t);
}

public class ExceptionReporter {

  // Exception reporter that prints the exception 
  // to the console (used as default)
  private static final Reporter PrintException = new Reporter() {
    public void report(Throwable t) {
      System.err.println(t.toString());
    }
  };

  // Stores the default reporter.
  // The default reporter can be changed by the user.
  private static Reporter Default = PrintException;

  // Helps change the default reporter back to 
  // PrintException in the future
  public static Reporter getPrintException() {
    return PrintException;
  }

  public static Reporter getExceptionReporter() {
    return Default;
  }

  // May throw a SecurityException (which is unchecked)
public static void setExceptionReporter(Reporter reporter) {
    // Custom permission
    ExceptionReporterPermission perm = new 
        ExceptionReporterPermission("exc.reporter"); 
    SecurityManager sm = System.getSecurityManager();
    if (sm != null) {
      // Check whether the caller has appropriate permissions
      sm.checkPermission(perm);
    }
    // Change the default exception reporter
    Default = reporter; 
  }
}

...

The library may subsequently use the exception reporter in catch clauses:

Code Block
bgColor#ccccff

try {
  // ...
} catch (IOException warning) {
  ExceptionReporter.getExceptionReporter().report(warning);
  // Recover from the exception...
}

Any client code that possesses the required permissions can override the ExceptionReporter with a handler that logs the error or provides a dialog box, or both. For example, a GUI client using Swing may require exceptions to be reported using a dialog box:

Code Block
bgColor#ccccff

ExceptionReporter.setExceptionReporter(new ExceptionReporter() {
  public void report(Throwable exception) {
    JOptionPane.showMessageDialog(frame,
                                  exception.toString,
                                  exception.getClass().getName(),
                                  JOptionPane.ERROR_MESSAGE);
  }});

...

Sometimes exceptions must be hidden from the user for security reasons (see rule ERR01-J. Do not allow exceptions to expose sensitive information. In such cases, one acceptable approach is to subclass the ExceptionReporter class and add a filter() method in addition to overriding the default report() method.

Code Block
bgColor#ccccff

class MyExceptionReporter extends ExceptionReporter {
  private static final Logger logger =
      Logger.getLogger("com.organization.Log");

  public static void report(Throwable t) {
    try {
      final Throwable filteredException =
          (t instanceof NonSensitiveException_1) ? t : filter(t);
    } finally {
      // Do any necessary user reporting
      // (show dialog box or send to console)
      if (filteredException instanceof NonSensitiveCommonException) {
        logger.log(Level.FINEST, "Loggable exception occurred", t);
      }
    }
  }

  public static Exception filter(Throwable t) {
    if (t instanceof SensitiveForLoggingException_1) { 
      // Do not log sensitive information (whitelist)
      return SensitiveCommonException();
    }
    // ...
    // Return for reporting to the user
    return new NonSensitiveCommonException(); 
  }
}

...

If a thread is interrupted while sleeping or waiting, it causes a java.lang.InterruptedException to be thrown. However, the run() method of interface Runnable cannot throw a checked exception and must handle InterruptedException. This noncompliant code example catches and suppresses InterruptedException.

Code Block
bgColor#FFCCCC

class Foo implements Runnable {
  public void run() {
    try {
      Thread.sleep(1000);
    } catch (InterruptedException e) {
      // Ignore
    }
  }
}

...

This compliant solution catches the InterruptedException and restores the interrupted status by calling the interrupt() method on the current thread.

Code Block
bgColor#ccccff

class Foo implements Runnable {
  public void run() {
    try {
      Thread.sleep(1000);
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt(); // Reset interrupted status
    }
  }
}

...

ERR00-EX1: When recovery from an exceptional condition is impossible at a particular abstraction level, code at that level must not handle that exceptional condition. In such cases, an appropriate exception must be thrown so that higher level code can catch the exceptional condition and can attempt recovery. The most common implementation for this case is to omit a catch block and allow the exception to propagate normally:

Code Block
bgColor#ccccff

// 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
}

Some APIs may limit the permissible exceptions thrown by particular methods. In such cases, it may be necessary to catch an exception and either wrap it in a permitted exception or translate it to one of the permitted exceptions.

Code Block
bgColor#ccccff

public void myMethod() throws MyProgramException {
  // ...
  try {
    // Requested file does not exist
    // User is unable to supply the file name
  } catch (FileNotFoundException e) {
    throw new MyProgramException(e);
  }
  // ...
}

...

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

ERR00-J

low

probable

medium

P4

L3

Automated Detection

Detection of suppressed exceptions is straightforward. Sound determination of which specific cases represent violations of this rule and which represent permitted exceptions to the rule is infeasible. Heuristic approaches may be effective.

Tool
Version
Checker
Description
Coverity7.5MISSING_THROWImplemented

Related Vulnerabilities

AMQ-1272 describes a vulnerability in the ActiveMQ service. When ActiveMQ receives an invalid username and password from a Stomp client, a security exception is generated but is subsequently ignored, leaving the client connected with full and unrestricted access to ActiveMQ.

...

[Bloch 2008]

Item 65. Don't ignore exceptions; Item 62. Document all exceptions thrown by each method

[Goetz 2006]

5.4, Blocking and interruptible methods

[JLS 2005]

Chapter 11, Exceptions

 

06. Exceptional Behavior (ERR)      06. Exceptional Behavior (ERR)