簡體   English   中英

鏈接異常,捕獲異常以拋出新異常

[英]Chaining exceptions, catching exceptions to throw new ones

想象以下代碼是某些程序(java)的一部分:

function z(){
try{
  //some code here, that might throw exceptions.
}catch (SomeException | SomeOtherException e){
  //some exception handling here.
}

function y(){
  z();
}

function x(){
  y();
}

想象一下,如果在函數z中引發了Some SomeException或SomeOtherException異常,則函數x和y不會按預期執行。 我們要編寫代碼,使函數x和y知道在函數z中引發了異常,並使它們相應地起作用。 最好的方法是什么?

function z() thrown FunctionZFailedException{
  try{
    //some code here, that might throw exceptions.
  }catch (SomeException | SomeOtherException e){
    throw new FunctionZFailedException();
  }
}

function y() throws FunctionYFailedException{
  try{
    z();
  }catch (FunctionZFailedException e){
    throw new FunctionYFailedException();
  }
}

function x(){
  try{
    y();
  }catch (FunctionYFailedException e){
   //Do something, like alerting user that something went wrong.
  }
}

這是否太過分了,那就是僅僅為了將其他異常“轉發”到更高的級別而聲明新的異常?

我認為我們也可以讓SomeException和SomeOtherException飛起來並在函數x中捕獲它們。 但是imo可能會彌補可讀性差的代碼,

例如,如果在函數z中捕獲的異常是SQLException和NoSuchAlgorithmException,而函數y是login()函數。 然后,函數x將嘗試調用login(),並捕獲SQLException | NoSuchAlgorithmException,如果讓這些異常簡單地飛到最高級別,或者捕獲LoginFailedException,如果我們立即捕獲每個異常,並讓它們拋出新的異常。 似乎捕獲LoginFailedException使代碼更具可讀性。

兩種方式都有各自的缺點(可讀性較低的代碼與引入許多異常),我想知道經驗豐富的Java程序員通常如何處理類似的情況。

大家對例外的一般想法也表示感謝

當您查看代碼(以及方法和異常的名稱)時,會發現方法及其引發的異常是否在同一抽象級別上。

如果您具有getInputStream()方法,則適當的異常將是IOException。 如果在getDatabaseConnection()中調用該方法,則應捕獲IOException並引發SQLException。 並且,如果您的saveCustomerToDatabase()方法需要此方法,則應拋出類似ProcessFailedException的錯誤。

我不是寫Javadocs的忠實擁護者,但有時您應該問自己:我是否可以使用相同的語言(例如,技術語言,業務語言等)為此方法及其異常編寫好的Javadoc? 如果為saveCustomerToDatabase()-Method編寫一個Javadoc引發IOException,則將遇到麻煩。

如果您對方法z()的當前設計感到滿意,並且希望方法y()x() “知道” z()發生了不好的情況,則可以讓z()在之后拋出異常吞下它。

public void z() {
    try {
        // some code here, that might throw exceptions.
    } catch (SomeException | SomeOtherException e) {
        // handle the exception and then rethrow it
        logger.log("An exception happened in z().");
        throw e;
    }
}

public void y() {
    try {
        z();
    } catch(Exception e) {
        // handle problem with z() and rethrow the exception
        logger.log("An exception happened when calling z().");
        throw e;
    }
}

public void x() {
    try {
        y();
    } catch(Exception e) {
        // handle problem with y()
        logger.log("An exception happened when calling y().");
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM