2012-04-24 27 views
2

我正在尋找清理當前正在處理的代碼庫的異常混亂。如何清理異常處理?

基本設置是這樣的。

我有一個是通過大量的類,看起來像這樣實現的接口:

public interface TerminalMessage<E> { 

    // Override for specific return data type. 
    public E send(TerminalStream stream) throws Exception; 
} 

這些類扔了很多不同的異常,如IOException異常,InterruptedException異常等

,因爲它是現在,我所做的就是調用getMessage()獲取捕獲的異常,並將此消息轉發給ui-code。

這不是很好,因爲我有時會向用戶顯示虛假消息,並且發現不需要的異常。

我想創建一個自定義的異常類(TerminalException),它將包裝所有這些類型的異常。

但是我不確定在哪裏做包裝,如果包裝是在第一次拋出異常(例如在輸出流中)或每個send()方法中完成的。前者具有不增加太多代碼的優點,但對於我來說,更有意義的是,流引發IOException而不是TerminalException。

上述設計並不能真正解決顯示給用戶的有時是壞信息,所以一些提示如何將拋出的異常轉換成對用戶有用的東西將是非常好的!

謝謝!

+2

我強烈建議你閱讀這篇文章http://onjava.com/pub/a/onjava/2003/11/19/exceptions.html?page=2 – aviad 2012-04-24 07:35:44

回答

2

自定義異常是一個非常好的主意,如果你有一個有用的信息就像一個錯誤代碼。

只是包裝一切與你的TerminalException,但不要忘了原因

OR

使用拋出的第一個TerminalException:

public class MyException extends Exception{ 
    String errorMessage; 

    public MyException(String message, Exception cause){ 
    super(); 

    if(cause instanceof MyException){ 
     // already wrapped 
     errorMessage= cause.getErrorMessage();   
     initCause(cause.getCause()); 
    } 
    else{ 
     // not my Exception 
     errorMessage=message; 
     initCause(cause); 
    } 
´    

    } 

} 
+0

所以拋出一個拋出一個異常封裝IOException異常的TerminalException級別(在我的自定義流類中)應該沒問題? – monoceres 2012-04-24 08:16:24

+1

@monoceres我會說你應該總是在「有意義」的地方發現異常。如果您的流類可以添加比IOException提供的更多信息(如文件名,文件中的行號或重要狀態),請捕獲它並拋出一個包括信息和IOException的新異常作爲原因。如果它不能添加新的信息,讓它起泡到一個能夠做到的層次。當然,你可以隨意多次重複,或者有意義。 – siegi 2012-04-24 19:33:35

1

另一個選擇可能是使用模板方法設計模式和「控制」其中的例外如下:

public abstract TerminalMessage<E> { 
    public abstract E doSend(TerminalStream stream); 
    public E send(TerminalStream stream) throws Exception { 
     // do common stuff here 
     try { 
      doSend(stream); 
     } 
     // catch more specific exceptions first 
     // handle all the exceptions accordingly here, thus controlling 
     // in one central location what will be thrown externally 
     catch(Exception) { 
     } 
    } 
} 

這樣,所有派生類的異常處理將是相同的和本地化的,並且派生類不需要做任何特殊的事情。

0

從我嘗試過的很多設計中,這是我最喜歡在一些項目中使用的最後一個。

public enum ExceptionCodes { 
     IOException("ioexception", false), 
     UserNotFound("usernotfond", true); 

     private static final String BUNDLE_NAME = "SOME_bundle_name"; 

     private final String bundleCode; 
     private final String isManagable; 

     ExceptionCodes(String bundleCode, String isManagable) { 
      this. ... 
      ... 
     } 

     public String message() { 
      // eventually get locale from somewhere, for example some threadLocal 
      return SomeBundleResolver.resolve(BUMDLE_NAME, bundleCode); 
     } 

     public Boolean isManagable() { 
      return isManagable; 
     } 
    } 

    public class MyGenericException extends RuntimeException { 
     private final ExceptionCodes exceptionCode; 
     private final Throwable throwable; 

     public MyException(ExceptionCodes exceptionCode) { 
      this.... 
      ... 
     } 

     public MyException(ExceptionCodes exceptionCode, Throwable throwable) { 
      this. ... 
      .... 
     } 

     public Boolean isManagable() { 
      return exceptionCode.isManagable(); 
     } 

     public String getMessage() { 
      return (throwable == null) ? super.getMessage() : throwable.getMessage(); 
     } 

     ... 
    } 

要點是異常代碼在一個地方管理。你可以添加自定義的屬性來枚舉類似錯誤代碼等。異常的許多問題之一是,如果你不知道如何處理異常,這是不可能的,你會知道如何處理上面的異常層。那麼只會發生兩種情況。任何異常都可以以某種格式顯示給用戶,或者系統必須以某種優雅的方式崩潰。屬性isManagable就是這個。如果例外情況不可管理系統必須關閉。所以這個異常只是在一般錯誤處理程序的頂層應用程序中處理。這樣你可以防止異常爆發。