2013-02-07 70 views
0

我開發了一個EJB服務,我的服務只能拋出一種類型的異常 - MyServiceException。即所有發生的異常都被包裝到MyServiceException中並重新投射到客戶端。但我不想向客戶端顯示堆棧跟蹤(出於安全原因),我只想記錄此堆棧跟蹤並僅向客戶端顯示錯誤消息。所以簡單地寫下面的代碼就足夠了:如何獲取重新包裝的異常消息?

catch (Exception e) { 
    logger.error("Error when creating account", e); 
    throw new MyServiceException("Error when creating account" + e.getMessage()); 
} 

但是如果我有堆棧的方法:1 -2 -3。方法3拋出有意義的異常與消息"Not enough money",所以我想將此消息顯示給客戶端。但方法2用新消息"Some problem with your credit card"重新包裝此異常,因此在方法1 中調用e.getMessage()將僅返回"Some problem with your credit card",而不是"Not enough money"。如何在此情況下使用異常?如何獲取我扔的所有消息?

回答

0

如果這是你的代碼,我會建議你以不同的方式包裝例外:

catch (Exception e) { 
    logger.error("Error when creating account", e); 
    throw new MyServiceException("Error when creating account" + e.getMessage(), e); 
} 

注意在MyServiceException構造函數的第二個參數。這個構造函數應該調用它的超類的super(message,throwable)構造函數。

如果這樣做,那麼你可以通過調用exception.getCause()方法獲得原始異常。並因此exception.getCause()。getMessage()獲取其原始消息。

通常,所有第三方API都會像上面描述的那樣執行異常封裝,所以在設計良好的庫中引用異常原因時應該沒有問題。

更新:組合異常消息並將它們與新行字符分開的代碼示例。我沒有測試過它,但我很確定它正在工作,更重要的是說明如何去做你正在嘗試做的事情:

private static String printExceptionMessages(Throwable throwable) { 
    StringBuilder result = new StringBuilder(); 
    Throwable t = throwable; 
    while (t != null) { 
     result.append(t.getMessage()); 
     result.append('\n'); 
     t = t.getCause(); 
    } 
    return result.toString(); 
} 
+0

好的。但是我怎麼知道我需要調用'exception.getCause()'多少次。如果異常被多次包裹會怎麼樣?換句話說,我希望所有的錯誤消息都會被我拋出,但不會向客戶端提供堆棧跟蹤。 – MyTitle

+0

您可以遞歸調用getCause(),直到它返回null。合同是空的原因表示拋出的第一個原始異常。 – ATrubka

+0

請參閱Throwable.printStackTrace(PrintStream s)方法的代碼。 – ATrubka