2016-12-20 1 views
3

en Java, il est recommandé de ne pas jeter des exceptions à l'intérieur finally section try-chatch bloc en raison de cacher la propagation de toute throwable non gérée qui a été jeté dans le bloc try ou catch. Cette pratique est une violation de niveau blocker selon le profil sonar par défaut.Comment gérer les exceptions jeter à l'intérieur finally en java

Sonar Error: Remove this throw statement from this finally block.

Veuillez prendre en compte l'extrait de code suivant. Par exemple: fermer le flux d'entrée à l'intérieur du bloc finally et gérer d'éventuelles exceptions lors de la fermeture du flux.

public void upload(File file) { 
     ChannelSftp c = (ChannelSftp) channel; 
     BufferedInputStream bis = new BufferedInputStream(file.toInputStream()); 
     try { 
      String uploadLocation = Files.simplifyPath(this.fileLocation + "/" + file.getName()); 
      c.put(bis, uploadLocation); 
     } catch (SftpException e) { 
      throw new IllegalTargetException("Error occurred while uploading " + e.getMessage()); 
     } finally { 
      try { 
       bis.close(); 
      } catch (IOException e) { 
       throw new UnsupportedOperationException("Exception occurred while closing Input stream " + e.getMessage()); 
      } 
     } 
    } 

Nous vous saurions gré de bien vouloir montrer la manière classique de gérer ces situations.

+7

comme sidenote, la solution la plus lisse serait l'utilisation de [essayer avec-ressources] (https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html) – SomeJavaGuy

+0

Merci pour le conseil. –

+1

Pensez à ce qui se passe lorsque le bloc finally est exécuté après le lancement de 'IllegalTargetException' et une autre' UnsupportedOperationException' est levée. Lequel de ceux que l'appelant aurait? La même chose est vraie avec les instructions de retour dans finally-blocks, vous falsifieriez le flux de contrôle qui mènera au désastre. – Thomas

Répondre

2

La meilleure façon de gérer ce problème est d'utiliser try-with-resource. Mais si quelqu'un veut fermer la connexion manuellement et montrer l'exception du bloc ou catch sans se cacher, l'extrait de code suivant est la solution.

public void upload(File file) throws IOException { 
    ChannelSftp c = (ChannelSftp) channel; 
    BufferedInputStream bis = new BufferedInputStream(file.toInputStream()); 
    SftpException sftpException = null; 
    try { 
     String uploadLocation = Files.simplifyPath(this.fileLocation + "/" + file.getName()); 
     c.put(bis, uploadLocation); 
    } catch (SftpException e) { 
     sftpException = e; 
     throw new IllegalTargetException("Error occurred while uploading " + e.getMessage()); 
    } finally { 
     if (sftpException != null) { 
      try { 
       bis.close(); 
      } catch (Throwable t) { 
       sftpException.addSuppressed(t); 
      } 
     } else { 
      bis.close(); 
     } 
    } 
}