Author: markt
Date: Fri Dec 5 09:36:12 2014
New Revision: 1643210
URL: http://svn.apache.org/viewvc?rev=1643210&view=rev
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=57252
Provide application configured error pages with a chance to handle an
async error before the built-in error reporting.
Modified:
tomcat/trunk/java/org/apache/catalina/core/StandardHostValve.java
tomcat/trunk/java/org/apache/catalina/valves/ErrorReportValve.java
Modified: tomcat/trunk/java/org/apache/catalina/core/StandardHostValve.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/StandardHostValve.java?rev=1643210&r1=1643209&r2=1643210&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/StandardHostValve.java (original)
+++ tomcat/trunk/java/org/apache/catalina/core/StandardHostValve.java Fri Dec
5 09:36:12 2014
@@ -120,9 +120,6 @@ final class StandardHostValve extends Va
boolean asyncAtStart = request.isAsync();
boolean asyncDispatching = request.isAsyncDispatching();
- // An async error page may dispatch to another resource. This flag
helps
- // ensure an infinite error handling loop is not entered
- boolean errorAtStart = response.isError();
try {
context.bind(Globals.IS_SECURITY_ENABLED, MY_CLASSLOADER);
@@ -135,18 +132,26 @@ final class StandardHostValve extends Va
return;
}
- // Ask this Context to process this request
+ // Ask this Context to process this request. Requests that are in
+ // async mode and are not being dispatched to this resource must be
+ // in error and have been routed here to check for application
+ // defined error pages.
try {
if (!asyncAtStart || asyncDispatching) {
context.getPipeline().getFirst().invoke(request, response);
} else {
- if (!errorAtStart) {
+ // Make sure this request/response is here because an error
+ // report is required.
+ if (!response.isErrorReportRequired()) {
throw new
IllegalStateException(sm.getString("standardHost.asyncStateError"));
}
}
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
- if (errorAtStart) {
+ // If a new error occurred while trying to report a previous
+ // error simply log the new error and allow the original error
+ // to be reported.
+ if (response.isErrorReportRequired()) {
container.getLogger().error("Exception Processing " +
request.getRequestURI(), t);
} else {
@@ -157,28 +162,27 @@ final class StandardHostValve extends Va
Throwable t = (Throwable)
request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
- // If the request was async at the start and an error occurred
- // then the async error handling will kick-in and that will fire
- // the request destroyed event *after* the error handling has
- // taken place.
- if (!(request.isAsync() || (asyncAtStart && t != null))) {
- // Protect against NPEs if context was destroyed during a
- // long running request.
- if (context.getState().isAvailable()) {
- if (!errorAtStart) {
- // Error page processing
- response.setSuspended(false);
-
- if (t != null) {
- throwable(request, response, t);
- } else {
- status(request, response);
- }
- }
+ // Protect against NPEs if the context was destroyed during a
+ // long running request.
+ if (!context.getState().isAvailable()) {
+ return;
+ }
+
+ // Look for (and render if found) an application level error page
+ if (response.isErrorReportRequired()) {
+ // Error page processing
+ response.setSuspended(false);
- context.fireRequestDestroyEvent(request);
+ if (t != null) {
+ throwable(request, response, t);
+ } else {
+ status(request, response);
}
}
+
+ if (!request.isAsync() && !response.isErrorReportRequired()) {
+ context.fireRequestDestroyEvent(request);
+ }
} finally {
// Access a session (if present) to update last accessed time,
based
// on a strict interpretation of the specification
Modified: tomcat/trunk/java/org/apache/catalina/valves/ErrorReportValve.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/valves/ErrorReportValve.java?rev=1643210&r1=1643209&r2=1643210&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/valves/ErrorReportValve.java
(original)
+++ tomcat/trunk/java/org/apache/catalina/valves/ErrorReportValve.java Fri Dec
5 09:36:12 2014
@@ -97,8 +97,10 @@ public class ErrorReportValve extends Va
Throwable throwable = (Throwable)
request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
- if (request.isAsyncStarted() && ((response.getStatus() < 400 &&
- throwable == null) || request.isAsyncDispatching())) {
+ // If an async request is in progress and is not going to end once this
+ // container thread finishes, do not trigger error page handling - it
+ // will be triggered later if required.
+ if (request.isAsync() && !request.isAsyncCompleting()) {
return;
}
@@ -122,11 +124,6 @@ public class ErrorReportValve extends Va
} catch (Throwable tt) {
ExceptionUtils.handleThrowable(tt);
}
-
- if (request.isAsyncStarted() && !request.isAsyncCompleting() &&
- !request.isAsyncDispatching()) {
- request.getAsyncContext().complete();
- }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]