@Override public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { Throwable cause = e.getCause(); if (cause instanceof IOException) { if (cause instanceof ClosedChannelException) { synchronized (ignoreClosedChannelExceptionLock) { if (ignoreClosedChannelException > 0) { ignoreClosedChannelException--; logger.debug("Swallowing an exception raised while " + "writing non-app data", cause); return; } } } else if (engine.isOutboundDone()) { String message = String.valueOf(cause.getMessage()).toLowerCase(); if (IGNORABLE_ERROR_MESSAGE.matcher(message).matches()) { // It is safe to ignore the 'connection reset by peer' or // 'broken pipe' error after sending closure_notify. logger.debug( "Swallowing a 'connection reset by peer / " + "broken pipe' error occurred while writing " + "'closure_notify'", cause); // Close the connection explicitly just in case the transport // did not close the connection automatically. Channels.close(ctx, succeededFuture(e.getChannel())); return; } } } ctx.sendUpstream(e); }
@Override protected void notifyHandlerException(ChannelEvent e, Throwable t) { while (t instanceof ChannelPipelineException && t.getCause() != null) { t = t.getCause(); } if (t instanceof CodecEmbedderException) { throw (CodecEmbedderException) t; } else { throw new CodecEmbedderException(t); } }