Skip to content

Commit a8dd5f6

Browse files
committed
If a 500 error view had errors in itself, Grails could get into a recursive
loop in certain circumstances. This change ensures that doesn't happen and simply displays a plain "Internal server error" page if the error view doesn't render for whatever reason.
1 parent 2c8a7ab commit a8dd5f6

File tree

2 files changed

+26
-5
lines changed

2 files changed

+26
-5
lines changed

src/java/org/codehaus/groovy/grails/web/servlet/GrailsApplicationAttributes.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ public interface GrailsApplicationAttributes extends ApplicationAttributes {
5757
String ACTION_NAME_ATTRIBUTE = "org.codehaus.groovy.grails.ACTION_NAME_ATTRIBUTE";
5858
String CONTROLLER_NAME_ATTRIBUTE = "org.codehaus.groovy.grails.CONTROLLER_NAME_ATTRIBUTE";
5959
String APP_URI_ATTRIBUTE = "org.codehaus.groovy.grails.APP_URI_ATTRIBUTE";
60+
String RENDERING_ERROR_ATTRIBUTE = "org.codehaus.groovy.grails.RENDERING_ERROR_ATTRIBUTE";
6061

6162
/**
6263
* Retrieves the plugin context path for the current request. The plugin context path is the path

src/java/org/codehaus/groovy/grails/web/servlet/GrailsDispatcherServlet.java

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -325,11 +325,31 @@ public Locale getLocale() {
325325

326326
try {
327327
render(mv, processedRequest, response);
328-
}
329-
catch (Exception e) {
330-
mv = super.processHandlerException(processedRequest, response, mappedHandler, e);
331-
handlerException = e;
332-
render(mv, processedRequest, response);
328+
} catch (Exception e) {
329+
// Only render the error view if we're not already trying to render it.
330+
// This prevents a recursion if the error page itself has errors.
331+
if (request.getAttribute(GrailsApplicationAttributes.RENDERING_ERROR_ATTRIBUTE) == null) {
332+
request.setAttribute(GrailsApplicationAttributes.RENDERING_ERROR_ATTRIBUTE, Boolean.TRUE);
333+
334+
mv = super.processHandlerException(processedRequest, response, mappedHandler, e);
335+
handlerException = e;
336+
render(mv, processedRequest, response);
337+
}
338+
else {
339+
request.removeAttribute(GrailsApplicationAttributes.RENDERING_ERROR_ATTRIBUTE);
340+
logger.warn("Recursive rendering of error view detected.", e);
341+
342+
try {
343+
response.setContentType("text/plain");
344+
response.getWriter().write("Internal server error");
345+
response.flushBuffer();
346+
} catch (Exception e2) {
347+
logger.error("Internal server error - problem rendering error view", e2);
348+
}
349+
350+
requestAttributes.setRenderView(false);
351+
return;
352+
}
333353
}
334354
}
335355
else {

0 commit comments

Comments
 (0)