diff --git a/src/main/java/org/redkale/net/ProtocolCodec.java b/src/main/java/org/redkale/net/ProtocolCodec.java index c1e787e66..5245b2e17 100644 --- a/src/main/java/org/redkale/net/ProtocolCodec.java +++ b/src/main/java/org/redkale/net/ProtocolCodec.java @@ -83,7 +83,7 @@ class ProtocolCodec implements CompletionHandler { decode(buffer, response, 0, null); } catch (Throwable t) { //此处不可 context.offerBuffer(buffer); 以免dispatcher.dispatch内部异常导致重复 offerBuffer context.logger.log(Level.WARNING, "dispatch servlet abort, force to close channel ", t); - response.error(t); + response.errorInIOCodec(t); } } @@ -104,7 +104,7 @@ class ProtocolCodec implements CompletionHandler { decode(data, response, 0, null); } catch (Throwable t) { context.logger.log(Level.WARNING, "dispatch servlet abort, force to close channel ", t); - response.error(t); + response.errorInIOCodec(t); } return; } @@ -125,7 +125,7 @@ class ProtocolCodec implements CompletionHandler { decode(data, response, 0, null); } catch (Throwable t) { context.logger.log(Level.WARNING, "dispatch servlet abort, force to close channel ", t); - response.error(t); + response.errorInIOCodec(t); } return; } @@ -150,7 +150,7 @@ class ProtocolCodec implements CompletionHandler { if (rs != Integer.MIN_VALUE) { dispatcher.incrIllegalRequestCounter(); } - response.error(null); + response.errorInIOCodec(null); if (context.logger.isLoggable(Level.FINEST)) { context.logger.log(Level.FINEST, "request.readHeader erroneous (" + rs + "), force to close channel "); } @@ -183,7 +183,7 @@ class ProtocolCodec implements CompletionHandler { decode(buffer, pipelineResponse, pindex + 1, hreq); } catch (Throwable t) { //此处不可 offerBuffer(buffer); 以免dispatcher.dispatch内部异常导致重复 offerBuffer context.logger.log(Level.WARNING, "dispatch pipeline servlet abort, force to close channel ", t); - pipelineResponse.error(t); + pipelineResponse.errorInIOCodec(t); } } } else { @@ -225,7 +225,7 @@ class ProtocolCodec implements CompletionHandler { public void failed(Throwable exc, ByteBuffer attachment) { context.dispatcher.incrIllegalRequestCounter(); channel.offerReadBuffer(attachment); - response.error(exc); + response.errorInIOCodec(exc); if (exc != null) { request.context.logger.log(Level.FINER, "Servlet continue read channel erroneous, force to close channel ", exc); } diff --git a/src/main/java/org/redkale/net/Response.java b/src/main/java/org/redkale/net/Response.java index 3e242dcbb..c92047127 100644 --- a/src/main/java/org/redkale/net/Response.java +++ b/src/main/java/org/redkale/net/Response.java @@ -49,6 +49,8 @@ public abstract class Response> { protected BiConsumer> recycleListener; + protected BiConsumer errorHandler; + protected List afterFinishListeners; protected Filter> filter; @@ -61,7 +63,7 @@ public abstract class Response> { @Override public void completed(Integer result, Void attachment) { - completeInIOThread(); + completeInIOThread(false); } @Override @@ -80,7 +82,7 @@ public abstract class Response> { } else { attachment.clear(); } - completeInIOThread(); + completeInIOThread(false); } @Override @@ -104,7 +106,7 @@ public abstract class Response> { channel.offerWriteBuffer(attachment); } } - completeInIOThread(); + completeInIOThread(false); } @Override @@ -242,6 +244,10 @@ public abstract class Response> { this.recycleListener = recycleListener; } + public void errorHandler(BiConsumer errorHandler) { + this.errorHandler = errorHandler; + } + public void addAfterFinishListener(Runnable listener) { if (this.afterFinishListeners == null) { this.afterFinishListeners = new ArrayList<>(); @@ -262,22 +268,43 @@ public abstract class Response> { return !this.inited; } - private void completeInIOThread() { - this.completeInIOThread(false); + /** + * Servlet.execute执行时报错 + * + * 被重载后kill不一定为true + * + * @param t Throwable + */ + public final void finishError(Throwable t) { + BiConsumer handler = this.errorHandler; + if (handler != null) { + this.errorHandler = null; + try { + handler.accept(request, t); + } catch (Throwable e) { + context.logger.log(Level.WARNING, "Response.errorHandler error, request = " + request, e); + defaultError(t); + } + } else { + defaultError(t); + } } - //被重载后kill不一定为true - protected void finishError(Throwable t) { - error(t); + protected void defaultError(Throwable t) { + errorInIOCodec(t); } - //kill=true - protected void error(Throwable t) { + /** + * 对请求包进行编解码时报错, 非Servlet.execute执行报错 + * + * @param t Throwable + */ + protected void errorInIOCodec(Throwable t) { completeInIOThread(true); } protected void completeFinishBytes(Integer result, Void attachment) { - completeInIOThread(); + completeInIOThread(false); } private void completeInIOThread(boolean kill) { diff --git a/src/main/java/org/redkale/net/http/HttpResponse.java b/src/main/java/org/redkale/net/http/HttpResponse.java index 3bb539e53..e6bdd7966 100644 --- a/src/main/java/org/redkale/net/http/HttpResponse.java +++ b/src/main/java/org/redkale/net/http/HttpResponse.java @@ -21,9 +21,9 @@ import org.redkale.convert.*; import org.redkale.convert.json.*; import org.redkale.net.*; import org.redkale.service.RetResult; +import org.redkale.util.*; import org.redkale.util.AnyValue.DefaultAnyValue; import org.redkale.util.AnyValue.Entry; -import org.redkale.util.*; import static org.redkale.util.Utility.append; /** @@ -329,7 +329,7 @@ public class HttpResponse extends Response { } @Override - protected void finishError(Throwable t) { + protected void defaultError(Throwable t) { finish(500, null); } @@ -944,12 +944,6 @@ public class HttpResponse extends Response { super.finish(false, data.content(), 0, data.length()); } - @Override - protected void error(Throwable t) { - refuseAlive(); - finish500(); - } - /** * 以304状态码输出 */ diff --git a/src/main/java/org/redkale/net/sncp/SncpResponse.java b/src/main/java/org/redkale/net/sncp/SncpResponse.java index 8392ab758..995de7d88 100644 --- a/src/main/java/org/redkale/net/sncp/SncpResponse.java +++ b/src/main/java/org/redkale/net/sncp/SncpResponse.java @@ -129,7 +129,7 @@ public class SncpResponse extends Response { } @Override - protected void finishError(Throwable t) { + protected void defaultError(Throwable t) { finish(RETCODE_THROWEXCEPTION, null); }