[#486] Make NoSuchBufferException give more useful message.

- Remove confusing exception messages
- Do not use default exception messages wherever possible
This commit is contained in:
Trustin Lee 2012-08-20 21:03:23 +09:00
parent ec2b29f0b6
commit b25996d024
5 changed files with 117 additions and 26 deletions

View File

@ -17,6 +17,8 @@ package io.netty.handler.codec;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandler;
import io.netty.channel.ChannelOutboundHandler;
import io.netty.channel.NoSuchBufferException; import io.netty.channel.NoSuchBufferException;
final class CodecUtil { final class CodecUtil {
@ -72,7 +74,12 @@ final class CodecUtil {
} }
} }
throw new NoSuchBufferException(); throw new NoSuchBufferException(String.format(
"the handler '%s' could not find a %s which accepts a %s.",
ctx.name(),
inbound? ChannelInboundHandler.class.getSimpleName()
: ChannelOutboundHandler.class.getSimpleName(),
msg.getClass().getSimpleName()));
} }
private CodecUtil() { private CodecUtil() {

View File

@ -44,12 +44,14 @@ public abstract class AbstractServerChannel extends AbstractChannel implements S
@Override @Override
public ByteBuf outboundByteBuffer() { public ByteBuf outboundByteBuffer() {
throw new NoSuchBufferException(); throw new NoSuchBufferException(String.format(
"%s does not have an outbound buffer.", ServerChannel.class.getSimpleName()));
} }
@Override @Override
public MessageBuf<Object> outboundMessageBuffer() { public MessageBuf<Object> outboundMessageBuffer() {
throw new NoSuchBufferException(); throw new NoSuchBufferException(String.format(
"%s does not have an outbound buffer.", ServerChannel.class.getSimpleName()));
} }
@Override @Override

View File

@ -366,7 +366,17 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
@Override @Override
public ByteBuf inboundByteBuffer() { public ByteBuf inboundByteBuffer() {
if (inByteBuf == null) { if (inByteBuf == null) {
throw new NoSuchBufferException(); if (handler instanceof ChannelInboundHandler) {
throw new NoSuchBufferException(String.format(
"the handler '%s' has no inbound byte buffer; it implements %s, but " +
"its newInboundBuffer() method created a %s.",
name, ChannelInboundHandler.class.getSimpleName(),
MessageBuf.class.getSimpleName()));
} else {
throw new NoSuchBufferException(String.format(
"the handler '%s' has no inbound byte buffer; it does not implement %s.",
name, ChannelInboundHandler.class.getSimpleName()));
}
} }
return inByteBuf; return inByteBuf;
} }
@ -375,7 +385,17 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T> MessageBuf<T> inboundMessageBuffer() { public <T> MessageBuf<T> inboundMessageBuffer() {
if (inMsgBuf == null) { if (inMsgBuf == null) {
throw new NoSuchBufferException(); if (handler instanceof ChannelInboundHandler) {
throw new NoSuchBufferException(String.format(
"the handler '%s' has no inbound message buffer; it implements %s, but " +
"its newInboundBuffer() method created a %s.",
name, ChannelInboundHandler.class.getSimpleName(),
ByteBuf.class.getSimpleName()));
} else {
throw new NoSuchBufferException(String.format(
"the handler '%s' has no inbound message buffer; it does not implement %s.",
name, ChannelInboundHandler.class.getSimpleName()));
}
} }
return (MessageBuf<T>) inMsgBuf; return (MessageBuf<T>) inMsgBuf;
} }
@ -393,7 +413,17 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
@Override @Override
public ByteBuf outboundByteBuffer() { public ByteBuf outboundByteBuffer() {
if (outByteBuf == null) { if (outByteBuf == null) {
throw new NoSuchBufferException(); if (handler instanceof ChannelOutboundHandler) {
throw new NoSuchBufferException(String.format(
"the handler '%s' has no outbound byte buffer; it implements %s, but " +
"its newOutboundBuffer() method created a %s.",
name, ChannelOutboundHandler.class.getSimpleName(),
MessageBuf.class.getSimpleName()));
} else {
throw new NoSuchBufferException(String.format(
"the handler '%s' has no outbound byte buffer; it does not implement %s.",
name, ChannelOutboundHandler.class.getSimpleName()));
}
} }
return outByteBuf; return outByteBuf;
} }
@ -402,7 +432,17 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T> MessageBuf<T> outboundMessageBuffer() { public <T> MessageBuf<T> outboundMessageBuffer() {
if (outMsgBuf == null) { if (outMsgBuf == null) {
throw new NoSuchBufferException(); if (handler instanceof ChannelOutboundHandler) {
throw new NoSuchBufferException(String.format(
"the handler '%s' has no outbound message buffer; it implements %s, but " +
"its newOutboundBuffer() method created a %s.",
name, ChannelOutboundHandler.class.getSimpleName(),
ByteBuf.class.getSimpleName()));
} else {
throw new NoSuchBufferException(String.format(
"the handler '%s' has no outbound message buffer; it does not implement %s.",
name, ChannelOutboundHandler.class.getSimpleName()));
}
} }
return (MessageBuf<T>) outMsgBuf; return (MessageBuf<T>) outMsgBuf;
} }
@ -451,7 +491,17 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
final Thread currentThread = Thread.currentThread(); final Thread currentThread = Thread.currentThread();
for (;;) { for (;;) {
if (ctx == null) { if (ctx == null) {
throw new NoSuchBufferException(); if (prev != null) {
throw new NoSuchBufferException(String.format(
"the handler '%s' could not find a %s whose inbound buffer is %s.",
name, ChannelInboundHandler.class.getSimpleName(),
ByteBuf.class.getSimpleName()));
} else {
throw new NoSuchBufferException(String.format(
"the pipeline does not contain a %s whose inbound buffer is %s.",
ChannelInboundHandler.class.getSimpleName(),
ByteBuf.class.getSimpleName()));
}
} }
if (ctx.inByteBuf != null) { if (ctx.inByteBuf != null) {
if (ctx.executor().inEventLoop(currentThread)) { if (ctx.executor().inEventLoop(currentThread)) {
@ -477,7 +527,17 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
final Thread currentThread = Thread.currentThread(); final Thread currentThread = Thread.currentThread();
for (;;) { for (;;) {
if (ctx == null) { if (ctx == null) {
throw new NoSuchBufferException(); if (prev != null) {
throw new NoSuchBufferException(String.format(
"the handler '%s' could not find a %s whose inbound buffer is %s.",
name, ChannelInboundHandler.class.getSimpleName(),
MessageBuf.class.getSimpleName()));
} else {
throw new NoSuchBufferException(String.format(
"the pipeline does not contain a %s whose inbound buffer is %s.",
ChannelInboundHandler.class.getSimpleName(),
MessageBuf.class.getSimpleName()));
}
} }
if (ctx.inMsgBuf != null) { if (ctx.inMsgBuf != null) {

View File

@ -18,7 +18,6 @@ package io.netty.channel;
import static io.netty.channel.DefaultChannelHandlerContext.*; import static io.netty.channel.DefaultChannelHandlerContext.*;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.ChannelBuf; import io.netty.buffer.ChannelBuf;
import io.netty.buffer.ChannelBufType;
import io.netty.buffer.MessageBuf; import io.netty.buffer.MessageBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.channel.DefaultChannelHandlerContext.ByteBridge; import io.netty.channel.DefaultChannelHandlerContext.ByteBridge;
@ -898,19 +897,11 @@ public class DefaultChannelPipeline implements ChannelPipeline {
@Override @Override
public MessageBuf<Object> inboundMessageBuffer() { public MessageBuf<Object> inboundMessageBuffer() {
if (channel.metadata().bufferType() != ChannelBufType.MESSAGE) {
throw new NoSuchBufferException(
"The first inbound buffer of this channel must be a message buffer.");
}
return head.nextInboundMessageBuffer(); return head.nextInboundMessageBuffer();
} }
@Override @Override
public ByteBuf inboundByteBuffer() { public ByteBuf inboundByteBuffer() {
if (channel.metadata().bufferType() != ChannelBufType.BYTE) {
throw new NoSuchBufferException(
"The first inbound buffer of this channel must be a byte buffer.");
}
return head.nextInboundByteBuffer(); return head.nextInboundByteBuffer();
} }
@ -951,10 +942,21 @@ public class DefaultChannelPipeline implements ChannelPipeline {
} }
ByteBuf nextOutboundByteBuffer(DefaultChannelHandlerContext ctx) { ByteBuf nextOutboundByteBuffer(DefaultChannelHandlerContext ctx) {
final DefaultChannelHandlerContext initialCtx = ctx;
final Thread currentThread = Thread.currentThread(); final Thread currentThread = Thread.currentThread();
for (;;) { for (;;) {
if (ctx == null) { if (ctx == null) {
throw new NoSuchBufferException(); if (initialCtx.next != null) {
throw new NoSuchBufferException(String.format(
"the handler '%s' could not find a %s whose outbound buffer is %s.",
initialCtx.next.name(), ChannelOutboundHandler.class.getSimpleName(),
ByteBuf.class.getSimpleName()));
} else {
throw new NoSuchBufferException(String.format(
"the pipeline does not contain a %s whose outbound buffer is %s.",
ChannelOutboundHandler.class.getSimpleName(),
ByteBuf.class.getSimpleName()));
}
} }
if (ctx.outByteBuf != null) { if (ctx.outByteBuf != null) {
@ -976,10 +978,21 @@ public class DefaultChannelPipeline implements ChannelPipeline {
} }
MessageBuf<Object> nextOutboundMessageBuffer(DefaultChannelHandlerContext ctx) { MessageBuf<Object> nextOutboundMessageBuffer(DefaultChannelHandlerContext ctx) {
final DefaultChannelHandlerContext initialCtx = ctx;
final Thread currentThread = Thread.currentThread(); final Thread currentThread = Thread.currentThread();
for (;;) { for (;;) {
if (ctx == null) { if (ctx == null) {
throw new NoSuchBufferException(); if (initialCtx.next != null) {
throw new NoSuchBufferException(String.format(
"the handler '%s' could not find a %s whose outbound buffer is %s.",
initialCtx.next.name(), ChannelOutboundHandler.class.getSimpleName(),
MessageBuf.class.getSimpleName()));
} else {
throw new NoSuchBufferException(String.format(
"the pipeline does not contain a %s whose outbound buffer is %s.",
ChannelOutboundHandler.class.getSimpleName(),
MessageBuf.class.getSimpleName()));
}
} }
if (ctx.outMsgBuf != null) { if (ctx.outMsgBuf != null) {
@ -1288,11 +1301,25 @@ public class DefaultChannelPipeline implements ChannelPipeline {
} }
validateFuture(future); validateFuture(future);
final DefaultChannelHandlerContext initialCtx = ctx;
EventExecutor executor; EventExecutor executor;
boolean msgBuf = false; boolean msgBuf = false;
for (;;) { for (;;) {
if (ctx == null) { if (ctx == null) {
throw new NoSuchBufferException(); if (initialCtx.next != null) {
throw new NoSuchBufferException(String.format(
"the handler '%s' could not find a %s which accepts a %s, and " +
"the transport does not accept it as-is.",
initialCtx.next.name(),
ChannelOutboundHandler.class.getSimpleName(),
message.getClass().getSimpleName()));
} else {
throw new NoSuchBufferException(String.format(
"the pipeline does not contain a %s which accepts a %s, and " +
"the transport does not accept it as-is.",
ChannelOutboundHandler.class.getSimpleName(),
message.getClass().getSimpleName()));
}
} }
if (ctx.hasOutboundMessageBuffer()) { if (ctx.hasOutboundMessageBuffer()) {

View File

@ -22,14 +22,9 @@ package io.netty.channel;
*/ */
public class NoSuchBufferException extends ChannelPipelineException { public class NoSuchBufferException extends ChannelPipelineException {
private static final String DEFAULT_MESSAGE =
"Could not find a suitable destination buffer. Double-check if the pipeline is " +
"configured correctly and its handlers works as expected.";
private static final long serialVersionUID = -131650785896627090L; private static final long serialVersionUID = -131650785896627090L;
public NoSuchBufferException() { public NoSuchBufferException() {
this(DEFAULT_MESSAGE);
} }
public NoSuchBufferException(String message, Throwable cause) { public NoSuchBufferException(String message, Throwable cause) {