S2221: Hit for rethrown exception

Rule S2221 checks that only thrown exceptions are caught using a catch clause. In particular, catching Exception (including RuntimeException) when not required by the signature of methods called in the try block is a code smell. This is perfectly fine if the exception were to be handled in the catch block and any runtime error were suppressed.
However, the rule is also triggered if Exception is caught and rethrown and nothing would be suppressed:

public class ErrorCatching {

  public void whatever() throws CheckedException {
    try {
    } catch (Exception ex) {
      try {
      } catch (Exception suppressed) {
      throw ex;

  private void compute() throws CheckedException {
    throw new CheckedException();

  private void clean() {
    throw new RuntimeException();

  private static class CheckedException extends Exception { }

Here, for both catch clauses an issue is raised. The outer exception is caught to do some necessary clean up, even in the case of runtime exceptions, and the actual exception handling is deferred to the caller. In the inner try-catch a RuntimeException could have been caught and no issue would have been created. In the case that clean() would throw a checked exception, this wouldn’t work.
With this approach neither ex nor suppressed are lost, the callee performed some house keeping and the exceptions are handled at the appropriate layer.

Hello @oliver

The outer exception is caught to do some necessary clean up, even in the case of runtime exceptions

If this is clear for you, why not making it clear for everyone by catching explicitly RuntimeException?
Indeed, the code can behave exactly as you intended, but in my understanding, the rule is not here to report “bugs” (a suppressed exception, …), but to warn that catching Exception is a code smell since it can lead to misunderstanding.

Does it make sense?