2014-01-16 15 views
3

在我的渠道管道中,有許多處理程序。在Netty 4中,我如何捕獲所有處理程序的未處理的exceptionCaught?

按我的理解,如果我不覆蓋其exceptionCaught(ChannelHandlerContext ctx, Throwable cause)方法,默認行爲是cause會拋出的管道,並通過管道WARN級別這樣的事情會被記錄:

An exception was thrown by a user handler's exceptionCaught() method while handling the following exception: ... 

我想覆蓋上面的管道行爲來添加一些特定的邏輯(例如:如果causejava.io.IOException: Connection reset by peer,不要記錄任何東西以避免WARN級別的太多「不太有用」的日誌)。

我該怎麼辦?

經過一番研究,我發現這個源代碼: https://github.com/netty/netty/blob/4.0/transport/src/main/java/io/netty/channel/DefaultChannelHandlerContext.java

private void invokeExceptionCaught(final Throwable cause) { 
    try { 
     handler.exceptionCaught(this, cause); 
    } catch (Throwable t) { 
     if (logger.isWarnEnabled()) { 
      logger.warn(
        "An exception was thrown by a user handler's " + 
        "exceptionCaught() method while handling the following exception:", cause); 
     } 
    } 
} 

因爲它是private,我不認爲我可以很容易地覆蓋它,而無需使用反射。有沒有更好的辦法?

回答

5

你可以通過定義一個ExceptionHandler來做到這一點,然後把這個處理程序放在管道尾部。

ChannelPipeline p = ch.pipeline(); 
p.addLast("business", new SomeBusinessHandler()); 
p.addLast... 
p.addLast("exception", new ExceptionHandler());//Make sure this is the last line when init the pipeline. 

並在exceptionCaught方法中編寫您的特定邏輯。但不要重新拋出異常,因爲這是管道的末端。

+0

我已檢查過。這個解決方案有效謝謝! –

1

不知道爲什麼你的exceptionCaught方法會拋出一個異常......我想你只是想重寫ChannelHandler.exceptionCaught(..)方法並在那裏處理它。

+0

當覆蓋所有入站處理程序的'exceptionCaught'時,我可以捕獲異常。但是因爲我在編寫web框架,框架用戶可以將用戶創建的處理程序(不會覆蓋)傳遞給框架,即使處理程序不重寫「exceptionCaught」,我也要捕獲所有異常。 –

+0

只要確保您始終擁有ChannelPipeline中的最後一個ChannelInboundHandler,它將覆蓋exceptionCaught(...) –

相關問題