diff --git a/common/src/main/java/io/netty/util/internal/ThrowableUtils.java b/common/src/main/java/io/netty/util/internal/ThrowableUtils.java new file mode 100644 index 0000000000..a592862584 --- /dev/null +++ b/common/src/main/java/io/netty/util/internal/ThrowableUtils.java @@ -0,0 +1,48 @@ +/* + * Copyright 2016 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package io.netty.util.internal; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.PrintStream; + +public final class ThrowableUtils { + + /** + *
Gets the stack trace from a Throwable as a String.
+ * + * @param throwable theThrowable
to be examined
+ * @return the stack trace as generated by the exception's
+ * printStackTrace(PrintWriter)
method
+ */
+ public static String stackTraceToString(Throwable cause) {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ PrintStream pout = new PrintStream(out);
+ cause.printStackTrace(pout);
+ pout.flush();
+ try {
+ return new String(out.toByteArray());
+ } finally {
+ try {
+ out.close();
+ } catch (IOException ignore) {
+ // ignore as should never happen
+ }
+ }
+ }
+
+ private ThrowableUtils() { }
+}
diff --git a/transport/src/main/java/io/netty/channel/AbstractChannelHandlerContext.java b/transport/src/main/java/io/netty/channel/AbstractChannelHandlerContext.java
index 2a051e1aa8..90f768800f 100644
--- a/transport/src/main/java/io/netty/channel/AbstractChannelHandlerContext.java
+++ b/transport/src/main/java/io/netty/channel/AbstractChannelHandlerContext.java
@@ -20,6 +20,7 @@ import io.netty.util.DefaultAttributeMap;
import io.netty.util.Recycler;
import io.netty.util.ReferenceCountUtil;
import io.netty.util.concurrent.EventExecutor;
+import io.netty.util.internal.ThrowableUtils;
import io.netty.util.internal.ObjectUtil;
import io.netty.util.internal.StringUtil;
import io.netty.util.internal.SystemPropertyUtil;
@@ -269,11 +270,18 @@ abstract class AbstractChannelHandlerContext extends DefaultAttributeMap impleme
if (isAdded()) {
try {
handler().exceptionCaught(this, cause);
- } catch (Throwable t) {
- if (logger.isWarnEnabled()) {
+ } catch (Throwable error) {
+ if (logger.isDebugEnabled()) {
+ logger.debug(
+ "An exception {}" +
+ "was thrown by a user handler's exceptionCaught() " +
+ "method while handling the following exception:",
+ ThrowableUtils.stackTraceToString(error), cause);
+ } else if (logger.isWarnEnabled()) {
logger.warn(
- "An exception was thrown by a user handler's " +
- "exceptionCaught() method while handling the following exception:", cause);
+ "An exception '{}' [enable DEBUG level for full stacktrace] " +
+ "was thrown by a user handler's exceptionCaught() " +
+ "method while handling the following exception:", error, cause);
}
}
} else {
diff --git a/transport/src/main/java/io/netty/channel/ChannelOutboundBuffer.java b/transport/src/main/java/io/netty/channel/ChannelOutboundBuffer.java
index 261d5e701b..e10ebbc51d 100644
--- a/transport/src/main/java/io/netty/channel/ChannelOutboundBuffer.java
+++ b/transport/src/main/java/io/netty/channel/ChannelOutboundBuffer.java
@@ -25,12 +25,10 @@ import io.netty.util.ReferenceCountUtil;
import io.netty.util.concurrent.FastThreadLocal;
import io.netty.util.internal.InternalThreadLocalMap;
import io.netty.util.internal.PlatformDependent;
+import io.netty.util.internal.ThrowableUtils;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.PrintStream;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.util.Arrays;
@@ -679,7 +677,7 @@ public final class ChannelOutboundBuffer {
} else {
logger.warn(
"Failed to mark a promise as success because it has failed already: {}, unnotified cause {}",
- promise, stackTraceToString(err));
+ promise, ThrowableUtils.stackTraceToString(err));
}
}
}
@@ -692,23 +690,7 @@ public final class ChannelOutboundBuffer {
} else {
logger.warn(
"Failed to mark a promise as failure because it hass failed already: {}, unnotified cause {}",
- promise, stackTraceToString(err), cause);
- }
- }
- }
-
- private static String stackTraceToString(Throwable cause) {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- PrintStream pout = new PrintStream(out);
- cause.printStackTrace(pout);
- pout.flush();
- try {
- return new String(out.toByteArray());
- } finally {
- try {
- out.close();
- } catch (IOException ignore) {
- // ignore as should never happen
+ promise, ThrowableUtils.stackTraceToString(err), cause);
}
}
}
diff --git a/transport/src/main/java/io/netty/channel/CombinedChannelDuplexHandler.java b/transport/src/main/java/io/netty/channel/CombinedChannelDuplexHandler.java
index 0f74a33905..cc10a3cd18 100644
--- a/transport/src/main/java/io/netty/channel/CombinedChannelDuplexHandler.java
+++ b/transport/src/main/java/io/netty/channel/CombinedChannelDuplexHandler.java
@@ -19,6 +19,7 @@ import io.netty.buffer.ByteBufAllocator;
import io.netty.util.Attribute;
import io.netty.util.AttributeKey;
import io.netty.util.concurrent.EventExecutor;
+import io.netty.util.internal.ThrowableUtils;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
@@ -142,10 +143,17 @@ public class CombinedChannelDuplexHandler