обработка ошибок исключения ответа обратной записи вызывает исключение и бесконечный цикл вызова исключения. - PullRequest
1 голос
/ 07 марта 2012

Я пытаюсь обобщить обработку ошибок для запросов HTTP и всегда отвечаю фактическим кодом ошибки HTTP и соответствующим сообщением.

Вот моя проблема: в моем обработчике, который расширяет SimpleChannelUpstreamHandler, исключение вызывается, когда исключение генерируется где-либо в стеке. Это хорошо. Плохая часть заключается в том, что когда я пытаюсь записать ответ клиенту с соответствующим HTTP-кодом и ответом, запись вызывает исключение, а затем программа переходит в бесконечный цикл с повторным вызовом exceptionCaught.

Это должно быть обычно выполненное задание. Как я могу сделать это правильно?

@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent event)
        throws Exception {

    try{
        logger.error("Error in handling call: ", event.getCause());
        HttpResponse httpResponse = buildHttpResponseObject(UNAUTHORIZED, new StringBuilder("Test"), false, null);

        // Write the response.
        // for some reason calling this next line causes an infinite loop of exceptionCaught, even with the
        // catch below.  No idea why.  Still investigating.  In the meantime, we don't have custom error code responses. 
        ChannelFuture future = event.getChannel().write(httpResponse);

        // Close the connection after the write operation is done, even if it's a keep-alive.
        future.addListener(ChannelFutureListener.CLOSE);
    }
    catch(Exception t){            
        logger.error("Unable to customize error response. ", t);
        event.getChannel().close();

    }
}

Вот исключения:

38161 [New I/O server worker #1-1] ERROR nettytests.http.snoop.HttpSnoopServerHandler - Error in handling call: 
javax.net.ssl.SSLHandshakeException: null cert chain
    at sun.security.ssl.Handshaker.checkThrown(Handshaker.java:1364)
    at sun.security.ssl.SSLEngineImpl.checkTaskThrown(SSLEngineImpl.java:513)
    at sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:790)
    at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:758)
    at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624)
    at org.jboss.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:931)
    at org.jboss.netty.handler.ssl.SslHandler.decode(SslHandler.java:649)
    at org.jboss.netty.handler.codec.frame.FrameDecoder.callDecode(FrameDecoder.java:288)
    at org.jboss.netty.handler.codec.frame.FrameDecoder.messageReceived(FrameDecoder.java:207)
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268)
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255)
    at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:343)
    at org.jboss.netty.channel.socket.nio.NioWorker.processSelectedKeys(NioWorker.java:274)
    at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:194)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)
Caused by: javax.net.ssl.SSLHandshakeException: null cert chain
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
    at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1639)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:278)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:266)
    at sun.security.ssl.ServerHandshaker.clientCertificate(ServerHandshaker.java:1627)
    at sun.security.ssl.ServerHandshaker.processMessage(ServerHandshaker.java:176)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)
    at sun.security.ssl.Handshaker$1.run(Handshaker.java:808)
    at sun.security.ssl.Handshaker$1.run(Handshaker.java:806)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.security.ssl.Handshaker$DelegatedTask.run(Handshaker.java:1301)
    at org.jboss.netty.handler.ssl.SslHandler$3.run(SslHandler.java:1060)
    at org.jboss.netty.handler.ssl.ImmediateExecutor.execute(ImmediateExecutor.java:31)
    at org.jboss.netty.handler.ssl.SslHandler.runDelegatedTasks(SslHandler.java:1057)
    at org.jboss.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:947)
    ... 11 more
38177 [New I/O server worker #1-1] ERROR nettytests.http.snoop.HttpSnoopServerHandler - Error in handling call: 
java.lang.IllegalStateException: cannot send more responses than requests
    at org.jboss.netty.handler.codec.http.HttpContentEncoder.writeRequested(HttpContentEncoder.java:104)
    at org.jboss.netty.channel.Channels.write(Channels.java:605)
    at org.jboss.netty.channel.Channels.write(Channels.java:572)
    at org.jboss.netty.channel.AbstractChannel.write(AbstractChannel.java:245)
    at nettytests.http.snoop.HttpSnoopServerHandler.exceptionCaught(HttpSnoopServerHandler.java:201)
    at nettytests.logger.RequestAuditLogger.handleUpstream(RequestAuditLogger.java:32)
    at org.jboss.netty.handler.codec.replay.ReplayingDecoder.exceptionCaught(ReplayingDecoder.java:456)
    at org.jboss.netty.handler.ssl.SslHandler.exceptionCaught(SslHandler.java:554)
    at org.jboss.netty.channel.Channels.fireExceptionCaught(Channels.java:426)
    at org.jboss.netty.channel.AbstractChannelSink.exceptionCaught(AbstractChannelSink.java:47)
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268)
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255)
    at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:343)
    at org.jboss.netty.channel.socket.nio.NioWorker.processSelectedKeys(NioWorker.java:274)
    at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:194)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)
38177 [New I/O server worker #1-1] ERROR nettytests.http.snoop.HttpSnoopServerHandler - Error in handling call: 
java.lang.IllegalStateException: cannot send more responses than requests
    at org.jboss.netty.handler.codec.http.HttpContentEncoder.writeRequested(HttpContentEncoder.java:104)
    at org.jboss.netty.channel.Channels.write(Channels.java:605)
    at org.jboss.netty.channel.Channels.write(Channels.java:572)
    at org.jboss.netty.channel.AbstractChannel.write(AbstractChannel.java:245)
    at nettytests.http.snoop.HttpSnoopServerHandler.exceptionCaught(HttpSnoopServerHandler.java:201)
    at nettytests.logger.RequestAuditLogger.handleUpstream(RequestAuditLogger.java:32)
    at org.jboss.netty.handler.codec.replay.ReplayingDecoder.exceptionCaught(ReplayingDecoder.java:456)
    at org.jboss.netty.handler.ssl.SslHandler.exceptionCaught(SslHandler.java:554)
    at org.jboss.netty.channel.Channels.fireExceptionCaught(Channels.java:426)
    at org.jboss.netty.channel.AbstractChannelSink.exceptionCaught(AbstractChannelSink.java:47)
    at org.jboss.netty.channel.Channels.write(Channels.java:605)
    at org.jboss.netty.channel.Channels.write(Channels.java:572)
    at org.jboss.netty.channel.AbstractChannel.write(AbstractChannel.java:245)
    at nettytests.http.snoop.HttpSnoopServerHandler.exceptionCaught(HttpSnoopServerHandler.java:201)
    at nettytests.logger.RequestAuditLogger.handleUpstream(RequestAuditLogger.java:32)
    at org.jboss.netty.handler.codec.replay.ReplayingDecoder.exceptionCaught(ReplayingDecoder.java:456)
    at org.jboss.netty.handler.ssl.SslHandler.exceptionCaught(SslHandler.java:554)
    at org.jboss.netty.channel.Channels.fireExceptionCaught(Channels.java:426)
    at org.jboss.netty.channel.AbstractChannelSink.exceptionCaught(AbstractChannelSink.java:47)
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268)
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255)
    at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:343)
    at org.jboss.netty.channel.socket.nio.NioWorker.processSelectedKeys(NioWorker.java:274)
    at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:194)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)
38224 [New I/O server worker #1-1] ERROR nettytests.http.snoop.HttpSnoopServerHandler - Error in handling call: 
java.lang.IllegalStateException: cannot send more responses than requests
    at org.jboss.netty.handler.codec.http.HttpContentEncoder.writeRequested(HttpContentEncoder.java:104)
    at org.jboss.netty.channel.Channels.write(Channels.java:605)
    at org.jboss.netty.channel.Channels.write(Channels.java:572)
    at org.jboss.netty.channel.AbstractChannel.write(AbstractChannel.java:245)
    at nettytests.http.snoop.HttpSnoopServerHandler.exceptionCaught(HttpSnoopServerHandler.java:201)
    at nettytests.logger.RequestAuditLogger.handleUpstream(RequestAuditLogger.java:32)
    at org.jboss.netty.handler.codec.replay.ReplayingDecoder.exceptionCaught(ReplayingDecoder.java:456)
    at org.jboss.netty.handler.ssl.SslHandler.exceptionCaught(SslHandler.java:554)
    at org.jboss.netty.channel.Channels.fireExceptionCaught(Channels.java:426)
    at org.jboss.netty.channel.AbstractChannelSink.exceptionCaught(AbstractChannelSink.java:47)
    at org.jboss.netty.channel.Channels.write(Channels.java:605)
    at org.jboss.netty.channel.Channels.write(Channels.java:572)
    at org.jboss.netty.channel.AbstractChannel.write(AbstractChannel.java:245)
    at nettytests.http.snoop.HttpSnoopServerHandler.exceptionCaught(HttpSnoopServerHandler.java:201)
    at nettytests.logger.RequestAuditLogger.handleUpstream(RequestAuditLogger.java:32)
    at org.jboss.netty.handler.codec.replay.ReplayingDecoder.exceptionCaught(ReplayingDecoder.java:456)
    at org.jboss.netty.handler.ssl.SslHandler.exceptionCaught(SslHandler.java:554)
    at org.jboss.netty.channel.Channels.fireExceptionCaught(Channels.java:426)
    at org.jboss.netty.channel.AbstractChannelSink.exceptionCaught(AbstractChannelSink.java:47)
    at org.jboss.netty.channel.Channels.write(Channels.java:605)
    at org.jboss.netty.channel.Channels.write(Channels.java:572)
    at org.jboss.netty.channel.AbstractChannel.write(AbstractChannel.java:245)
    at nettytests.http.snoop.HttpSnoopServerHandler.exceptionCaught(HttpSnoopServerHandler.java:201)
    at nettytests.logger.RequestAuditLogger.handleUpstream(RequestAuditLogger.java:32)
    at org.jboss.netty.handler.codec.replay.ReplayingDecoder.exceptionCaught(ReplayingDecoder.java:456)
    at org.jboss.netty.handler.ssl.SslHandler.exceptionCaught(SslHandler.java:554)
    at org.jboss.netty.channel.Channels.fireExceptionCaught(Channels.java:426)
    at org.jboss.netty.channel.AbstractChannelSink.exceptionCaught(AbstractChannelSink.java:47)
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268)
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255)
    at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:343)
    at org.jboss.netty.channel.socket.nio.NioWorker.processSelectedKeys(NioWorker.java:274)
    at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:194)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)
38255 [New I/O server worker #1-1] ERROR nettytests.http.snoop.HttpSnoopServerHandler - Error in handling call: 
java.lang.IllegalStateException: cannot send more responses than requests
    at org.jboss.netty.handler.codec.http.HttpContentEncoder.writeRequested(HttpContentEncoder.java:104)
    at org.jboss.netty.channel.Channels.write(Channels.java:605)
    at org.jboss.netty.channel.Channels.write(Channels.java:572)
    at org.jboss.netty.channel.AbstractChannel.write(AbstractChannel.java:245)
    at nettytests.http.snoop.HttpSnoopServerHandler.exceptionCaught(HttpSnoopServerHandler.java:201)
    at nettytests.logger.RequestAuditLogger.handleUpstream(RequestAuditLogger.java:32)
    at org.jboss.netty.handler.codec.replay.ReplayingDecoder.exceptionCaught(ReplayingDecoder.java:456)
    at org.jboss.netty.handler.ssl.SslHandler.exceptionCaught(SslHandler.java:554)
    at org.jboss.netty.channel.Channels.fireExceptionCaught(Channels.java:426)
    at org.jboss.netty.channel.AbstractChannelSink.exceptionCaught(AbstractChannelSink.java:47)
    at org.jboss.netty.channel.Channels.write(Channels.java:605)
    at org.jboss.netty.channel.Channels.write(Channels.java:572)
    at org.jboss.netty.channel.AbstractChannel.write(AbstractChannel.java:245)
    at nettytests.http.snoop.HttpSnoopServerHandler.exceptionCaught(HttpSnoopServerHandler.java:201)
    at nettytests.logger.RequestAuditLogger.handleUpstream(RequestAuditLogger.java:32)
    at org.jboss.netty.handler.codec.replay.ReplayingDecoder.exceptionCaught(ReplayingDecoder.java:456)
    at org.jboss.netty.handler.ssl.SslHandler.exceptionCaught(SslHandler.java:554)
    at org.jboss.netty.channel.Channels.fireExceptionCaught(Channels.java:426)
    at org.jboss.netty.channel.AbstractChannelSink.exceptionCaught(AbstractChannelSink.java:47)
    at org.jboss.netty.channel.Channels.write(Channels.java:605)
    at org.jboss.netty.channel.Channels.write(Channels.java:572)
    at org.jboss.netty.channel.AbstractChannel.write(AbstractChannel.java:245)
    at nettytests.http.snoop.HttpSnoopServerHandler.exceptionCaught(HttpSnoopServerHandler.java:201)
    at nettytests.logger.RequestAuditLogger.handleUpstream(RequestAuditLogger.java:32)
    at org.jboss.netty.handler.codec.replay.ReplayingDecoder.exceptionCaught(ReplayingDecoder.java:456)
    at org.jboss.netty.handler.ssl.SslHandler.exceptionCaught(SslHandler.java:554)
    at org.jboss.netty.channel.Channels.fireExceptionCaught(Channels.java:426)
    at org.jboss.netty.channel.AbstractChannelSink.exceptionCaught(AbstractChannelSink.java:47)
    at org.jboss.netty.channel.Channels.write(Channels.java:605)
    at org.jboss.netty.channel.Channels.write(Channels.java:572)
    at org.jboss.netty.channel.AbstractChannel.write(AbstractChannel.java:245)
    at nettytests.http.snoop.HttpSnoopServerHandler.exceptionCaught(HttpSnoopServerHandler.java:201)
    at nettytests.logger.RequestAuditLogger.handleUpstream(RequestAuditLogger.java:32)
    at org.jboss.netty.handler.codec.replay.ReplayingDecoder.exceptionCaught(ReplayingDecoder.java:456)
    at org.jboss.netty.handler.ssl.SslHandler.exceptionCaught(SslHandler.java:554)
    at org.jboss.netty.channel.Channels.fireExceptionCaught(Channels.java:426)
    at org.jboss.netty.channel.AbstractChannelSink.exceptionCaught(AbstractChannelSink.java:47)
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268)
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255)
    at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:343)
    at org.jboss.netty.channel.socket.nio.NioWorker.processSelectedKeys(NioWorker.java:274)
    at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:194)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)

... повторить до бесконечности.

1 Ответ

2 голосов
/ 07 марта 2012

Бесконечный цикл плохой ... я заметил, что вы вызываете Channel.close () в блоке finally.В большинстве случаев это случится прежде, чем вы сможете что-то написать на канал.Вы должны использовать

future.addListener (ChannelFutureListener.CLOSE);

, чтобы закрыть канал после того, как вы что-то написали.Это должно даже быть вызвано на исключение

...