Do not treat errors as decoder exception (redux)

Motivation: Today when Netty encounters a general error while decoding
it treats this as a decoder exception. However, for fatal causes this
should not be treated as such, instead the fatal error should be carried
up the stack without the callee having to unwind causes. This was
probably done for byte to byte message decoder but is now done for all
decoders.

Modifications: Instead of translating any error to a decoder exception,
we let those unwind out the stack (note that finally blocks still
execute) except in places where an event needs to fire where we fire
with the error instead of wrapping in a decoder exception.

Result: Fatal errors will not be treated as innocent decoder exceptions.
This commit is contained in:
Jason Tedor 2017-10-04 12:06:59 -04:00 committed by Norman Maurer
parent 3cca5dfa92
commit 3fe1f71511
12 changed files with 22 additions and 16 deletions

View File

@ -355,16 +355,16 @@ public class HAProxyMessageDecoder extends ByteToMessageDecoder {
fail(ctx, "header length (" + length + ") exceeds the allowed maximum (" + maxLength + ')', null);
}
private void fail(final ChannelHandlerContext ctx, String errMsg, Throwable t) {
private void fail(final ChannelHandlerContext ctx, String errMsg, Exception e) {
finished = true;
ctx.close(); // drop connection immediately per spec
HAProxyProtocolException ppex;
if (errMsg != null && t != null) {
ppex = new HAProxyProtocolException(errMsg, t);
if (errMsg != null && e != null) {
ppex = new HAProxyProtocolException(errMsg, e);
} else if (errMsg != null) {
ppex = new HAProxyProtocolException(errMsg);
} else if (t != null) {
ppex = new HAProxyProtocolException(t);
} else if (e != null) {
ppex = new HAProxyProtocolException(e);
} else {
ppex = new HAProxyProtocolException();
}

View File

@ -78,7 +78,7 @@ public class Socks4ClientDecoder extends ReplayingDecoder<State> {
}
}
private void fail(List<Object> out, Throwable cause) {
private void fail(List<Object> out, Exception cause) {
if (!(cause instanceof DecoderException)) {
cause = new DecoderException(cause);
}

View File

@ -99,7 +99,7 @@ public class Socks4ServerDecoder extends ReplayingDecoder<State> {
}
}
private void fail(List<Object> out, Throwable cause) {
private void fail(List<Object> out, Exception cause) {
if (!(cause instanceof DecoderException)) {
cause = new DecoderException(cause);
}

View File

@ -92,7 +92,7 @@ public class Socks5CommandRequestDecoder extends ReplayingDecoder<State> {
}
}
private void fail(List<Object> out, Throwable cause) {
private void fail(List<Object> out, Exception cause) {
if (!(cause instanceof DecoderException)) {
cause = new DecoderException(cause);
}

View File

@ -91,7 +91,7 @@ public class Socks5CommandResponseDecoder extends ReplayingDecoder<State> {
}
}
private void fail(List<Object> out, Throwable cause) {
private void fail(List<Object> out, Exception cause) {
if (!(cause instanceof DecoderException)) {
cause = new DecoderException(cause);
}

View File

@ -85,7 +85,7 @@ public class Socks5InitialRequestDecoder extends ReplayingDecoder<State> {
}
}
private void fail(List<Object> out, Throwable cause) {
private void fail(List<Object> out, Exception cause) {
if (!(cause instanceof DecoderException)) {
cause = new DecoderException(cause);
}

View File

@ -76,7 +76,7 @@ public class Socks5InitialResponseDecoder extends ReplayingDecoder<State> {
}
}
private void fail(List<Object> out, Throwable cause) {
private void fail(List<Object> out, Exception cause) {
if (!(cause instanceof DecoderException)) {
cause = new DecoderException(cause);
}

View File

@ -83,7 +83,7 @@ public class Socks5PasswordAuthRequestDecoder extends ReplayingDecoder<State> {
}
}
private void fail(List<Object> out, Throwable cause) {
private void fail(List<Object> out, Exception cause) {
if (!(cause instanceof DecoderException)) {
cause = new DecoderException(cause);
}

View File

@ -73,7 +73,7 @@ public class Socks5PasswordAuthResponseDecoder extends ReplayingDecoder<State> {
}
}
private void fail(List<Object> out, Throwable cause) {
private void fail(List<Object> out, Exception cause) {
if (!(cause instanceof DecoderException)) {
cause = new DecoderException(cause);
}

View File

@ -418,7 +418,7 @@ public abstract class ReplayingDecoder<S> extends ByteToMessageDecoder {
}
} catch (DecoderException e) {
throw e;
} catch (Throwable cause) {
} catch (Exception cause) {
throw new DecoderException(cause);
}
}

View File

@ -234,8 +234,10 @@ public abstract class AbstractSniHandler<T> extends ByteToMessageDecoder impleme
onLookupComplete(ctx, hostname, future);
} catch (DecoderException err) {
ctx.fireExceptionCaught(err);
} catch (Throwable cause) {
} catch (Exception cause) {
ctx.fireExceptionCaught(new DecoderException(cause));
} catch (Throwable cause) {
ctx.fireExceptionCaught(cause);
}
} finally {
if (readPending) {

View File

@ -100,7 +100,11 @@ public class SniHandler extends AbstractSniHandler<SslContext> {
protected final void onLookupComplete(ChannelHandlerContext ctx,
String hostname, Future<SslContext> future) throws Exception {
if (!future.isSuccess()) {
throw new DecoderException("failed to get the SslContext for " + hostname, future.cause());
final Throwable cause = future.cause();
if (cause instanceof Error) {
throw (Error) cause;
}
throw new DecoderException("failed to get the SslContext for " + hostname, cause);
}
SslContext sslContext = future.getNow();