2015-01-28 12 views
7

Tôi đang sử dụng SonarQube cho chất lượng mã. Tôi đã có một vấn đề liên quan đến xử lý ngoại lệ, trong đó nói loại bỏ khoản ném từ cuối cùng khối.Làm thế nào để tránh điều khoản ném cuối cùng là chặn

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

Dựa trên sự hiểu biết của tôi ở trên mã có vẻ tốt. Nếu tôi loại bỏ điều khoản ném và ngăn chặn ngoại lệ trong cuối cùng sau đó người gọi của phương pháp này sẽ không thể biết trạng thái của máy chủ. Tôi không chắc chắn làm thế nào chúng ta có thể đạt được chức năng tương tự mà không có điều khoản ném.

+0

Bạn đã thử thêm một khối 'cuối cùng' vào khối' try-catch' bên trong đó và xem liệu nó có cảnh báo không? – Vikdor

+0

Nếu bạn đã sử dụng mệnh đề ném để chỉ ra các lỗi khác trong cùng một hàm, có lẽ sẽ không khôn ngoan khi sử dụng một phương pháp khác cho trường hợp cụ thể này? – Troyseph

+0

Ồ, tôi nghĩ bạn đang lo lắng bởi vì ngay cả khi kết nối không bao giờ được thực hiện thành công, khối 'cuối cùng' của bạn vẫn ném 'MyException' của bạn, tôi có đúng không? – Troyseph

Trả lời

5

bắn tốt nhất của bạn là sử dụng các tính năng Automatic Resource Management của Java, có sẵn từ Java 7. Nếu đó là vì một lý do không có sẵn cho bạn, sau đó là điều tốt nhất tiếp theo là tái tạo những gì mà đường cú pháp mở rộng thành:

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

những điều cần lưu ý:

  • mã của bạn nuốt ngoại lệ ban đầu từ khối try trong trường hợp đóng tài nguyên thất bại. Ngoại lệ ban đầu chắc chắn quan trọng hơn đối với chẩn đoán;
  • trong thành ngữ ARM ở trên, đóng tài nguyên được thực hiện khác nhau tùy thuộc vào việc đã có ngoại lệ trong khối thử hay chưa. Nếu try hoàn thành bình thường, thì tài nguyên được đóng bên ngoài bất kỳ khối try-catch nào, tự nhiên lan truyền bất kỳ ngoại lệ nào.
2

Nói chung, các phương pháp trong khối finally là mã 'dọn dẹp' (Đóng Connection, v.v.) mà người dùng không nhất thiết cần phải biết.

Những gì tôi làm cho những ngoại lệ này là hấp thụ ngoại lệ, nhưng ghi nhật ký chi tiết.

finally{ 
    try{ 
     connection.close(); 
    }catch(SQLException e){ 
     // do nothing and just log the error 
     LOG.error("Something happened while closing connection. Cause: " + e.getMessage()); 
    } 
} 
0

Tôi không chắc chắn như thế nào chúng ta có thể đạt được cùng một chức năng mà không cần phải khoản ném.

Bạn có thể tổ hai try khối khác nhau để đạt được kết quả tương tự:

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

Bạn đang nhận được một cảnh báo vì mã này có khả năng có thể ném một ngoại lệ khi giao dịch với một ngoại lệ ném. Bạn có thể sử dụng số thử với cú pháp tài nguyên để tự động đóng tài nguyên. Read more here.

Trong trường hợp ngoại lệ "yêu cầu không thành công:" được ném và bạn không đóng httpclient, ngoại lệ thứ hai là trường hợp sẽ phát sinh.

Các vấn đề liên quan