Avoiding a throw clause in a finally block

I use SonarQube for quality code. I have one problem with exception handling, which says that the throw clause needs to be removed from the 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, the code looks good. If I delete the throw clause and throw an exception, then the caller of this method will not be able to find out the status of the server. I'm not sure how we can achieve the same functionality without having a throw clause.

+7
java
source share
4 answers

It’s best to use the Automatic Java Resource Management feature available with Java 7. If this is not available to you for some reason, then the next best thing is to reproduce the fact that this syntactic sugar expands:

 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(); } } } 

Notes:

  • your code swallows the original exception from the try block in the event of a resource failure. The initial exception is certainly more important for diagnosis;
  • in the ARM idiom above, closing a resource is done differently depending on whether there has already been an exception in the try block. If try completes normally, then the resource closes outside any try-catch block, naturally throwing any exception.
+5
source share

Typically, the methods in the finally block are cleaning codes (closing Connection , etc.) that the user does not need to know.

What I do for these exceptions is to absorb the exception, but the log 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()); } } 
+2
source share

You get a warning because this code could potentially throw an exception when dealing with a thrown exception. You can use try syntax with the resource to automatically close the resource. More details here .

In the case where the exception "request failed:" is thrown and you cannot close httpclient, the second exception is the one that will bubble.

+1
source share

I'm not sure how we can achieve the same functionality without having throw.

You can split the two try blocks differently to achieve the same result:

 HttpClient httpClient = null; // initialize try { try { // do something with httpClient } catch(Exception e) { throw new MyException("request failed : ", e); } finally { httpClient.close(); } } catch (IOException e) { throw new MyException("failed to close server conn: ", e); } 
0
source share

All Articles