Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid throw clause in finally block

Tags:

java

I am using SonarQube for code quality. I got one issue related to exception handling, which says remove throw clause from finally block.

} catch(Exception e) {
            throw new MyException("request failed : ", e);
        } finally {
            try {
                httpClient.close();
            } catch (IOException e) {               
                throw new MyException("failed to close server conn: ", e);
            }
        }

Based on my understanding above code looks good. If I remove throw clause and suppress exception in finally then caller of this method will not be able to know server's status. I am not sure how we can achieve same functionality without having throw clause.

like image 260
ManojP Avatar asked Jan 28 '15 08:01

ManojP


2 Answers

Your best shot is to use the Automatic Resource Management feature of Java, available since Java 7. If that is for some reason not available to you, then the next best thing is to replicate what that syntactic sugar expands into:

public static void runWithoutMasking() throws MyException {
   AutoClose autoClose = new AutoClose();
   MyException myException = null;
   try {
       autoClose.work();
   } catch (MyException e) {
       myException = e;
       throw e;
   } finally {
       if (myException != null) {
           try {
               autoClose.close();
           } catch (Throwable t) {
               myException.addSuppressed(t);
           }
       } else {
           autoClose.close();
       }
   }
}

Things to note:

  • your code swallows the original exception from the try block in case closing the resource fails. The original exception is surely more important for diagnostic;
  • in the ARM idiom above, closing the resource is done differently depending on whether there already was an exception in the try-block. If try completed normally, then the resource is closed outside any try-catch block, naturally propagating any exception.
like image 96
Marko Topolnik Avatar answered Nov 10 '22 18:11

Marko Topolnik


Generally, methods in the finally block are 'cleanup' codes (Closing the Connection, etc) which the user does not necessarily need to know.

What I do for these exceptions is to absorb the exception, but log the details.

finally{
   try{
      connection.close();
   }catch(SQLException e){
      // do nothing and just log the error
      LOG.error("Something happened while closing connection. Cause: " + e.getMessage());
   }
}
like image 34
jmcg Avatar answered Nov 10 '22 19:11

jmcg