Expand my Community achievements bar.

Learn about Edge Delivery Services in upcoming GEM session
SOLVED

how to handle 500 error

Avatar

Level 6

I'm trying to show custom error message for 404/403/500 error. I'm able to show 404/403 error but unable to show 500 error. Steps I have followed so far - Step 1: Created a servlet which will set the status as 500 for testing purpose 

public class ErrorServlet extends SlingSafeMethodsServlet {

@Override protected void doGet(final SlingHttpServletRequest request, final SlingHttpServletResponse response) throws ServletException, IOException { try{

response.setStatus(500);

} catch (Exception e) { e.printStackTrace(); } } }

Step2: Crated Exception.jsp and Throwable.jsp under apps/sling/servlet/errorhandler

Step3: Added below code in both Exception.jsp and Throwable.jsp

<%@include file="/libs/foundation/global.jsp"%> <%@taglib prefix="sling" uri="http://sling.apache.org/taglibs/sling/1.0" %><% %><sling:defineObjects /><% response.setStatus(500); request.getRequestDispatcher("/content/myproject/en_US/ errorpages/errorpage500.html").forward(request,response); %>

Now when I hit http://port:host/path/to/servlet then I get "Internal Server Error" in the browser. It does not send to the expected custom error page which I mentioned. Kindly let me know what I'm missing here.

1 Accepted Solution

Avatar

Correct answer by
Level 2

You are just setting the 500 status, which is not picked by your error handler(which is wrongly implemented of course) , actually the sling "default" error handler kicks in and sends the "Internal Server Error".

you have two options:

// 1.

500.jsp script can be created. However, it is only used if HttpServletResponse.sendError(500) is executed explicitly; i.e. from an exception catcher.

Otherwise, the response code is set to 500, but the 500.jsp script is not executed..

You are not doing this in your servlet code.

 

// 2.

Update you error servlet as given below.

 

/** * Generic Error Handler Servlet that handles all the uncaught exceptions thrown by application code. * * @author Rakesh.Kumar * */ @Component(immediate = true) @SlingServlet(description = "Generic Error Handler Servlet that handles all the uncaught exceptions thrown by application code.", resourceTypes = { "sling/servlet/errorhandler" }, extensions = { "Throwable" }, generateComponent = false) public class ErrorHandlerServlet extends SlingAllMethodsServlet { /** * serialVersionUID for this class. */ private static final long serialVersionUID = -7199024830200774412L; /** * Logger for this class */ private static final Logger LOGGER = LoggerFactory .getLogger(ErrorHandlerServlet.class); /** * Generic Error Handler Servlet that handles all the uncaught exceptions * thrown by application code * * @param request *            {@link SlingHttpServletRequest} * @param response *            {@link SlingHttpServletResponse} * * @throws ServletException * @throws IOException */ @Override protected void service(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException { LOGGER.debug("Handling the uncaught exception."); Object exception = request.getAttribute(SlingConstants.ERROR_EXCEPTION); if (exception instanceof Exception) { Exception ex = (Exception) exception; String message = (String) request .getAttribute(SlingConstants.ERROR_MESSAGE); Integer statusCode = (Integer) request .getAttribute(SlingConstants.ERROR_STATUS); if (statusCode == null) { statusCode = Integer .valueOf(SlingHttpServletResponse.SC_INTERNAL_SERVER_ERROR); } // Logs the exception and other information. // forward/redirect your request to desired page and before that make sure response is not committed response.isCommitted } } }

Now for all uncaught exceptions(500) your Error handler will be called.

 

HTH.

~cheers

Rakesh

View solution in original post

4 Replies

Avatar

Correct answer by
Level 2

You are just setting the 500 status, which is not picked by your error handler(which is wrongly implemented of course) , actually the sling "default" error handler kicks in and sends the "Internal Server Error".

you have two options:

// 1.

500.jsp script can be created. However, it is only used if HttpServletResponse.sendError(500) is executed explicitly; i.e. from an exception catcher.

Otherwise, the response code is set to 500, but the 500.jsp script is not executed..

You are not doing this in your servlet code.

 

// 2.

Update you error servlet as given below.

 

/** * Generic Error Handler Servlet that handles all the uncaught exceptions thrown by application code. * * @author Rakesh.Kumar * */ @Component(immediate = true) @SlingServlet(description = "Generic Error Handler Servlet that handles all the uncaught exceptions thrown by application code.", resourceTypes = { "sling/servlet/errorhandler" }, extensions = { "Throwable" }, generateComponent = false) public class ErrorHandlerServlet extends SlingAllMethodsServlet { /** * serialVersionUID for this class. */ private static final long serialVersionUID = -7199024830200774412L; /** * Logger for this class */ private static final Logger LOGGER = LoggerFactory .getLogger(ErrorHandlerServlet.class); /** * Generic Error Handler Servlet that handles all the uncaught exceptions * thrown by application code * * @param request *            {@link SlingHttpServletRequest} * @param response *            {@link SlingHttpServletResponse} * * @throws ServletException * @throws IOException */ @Override protected void service(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException { LOGGER.debug("Handling the uncaught exception."); Object exception = request.getAttribute(SlingConstants.ERROR_EXCEPTION); if (exception instanceof Exception) { Exception ex = (Exception) exception; String message = (String) request .getAttribute(SlingConstants.ERROR_MESSAGE); Integer statusCode = (Integer) request .getAttribute(SlingConstants.ERROR_STATUS); if (statusCode == null) { statusCode = Integer .valueOf(SlingHttpServletResponse.SC_INTERNAL_SERVER_ERROR); } // Logs the exception and other information. // forward/redirect your request to desired page and before that make sure response is not committed response.isCommitted } } }

Now for all uncaught exceptions(500) your Error handler will be called.

 

HTH.

~cheers

Rakesh

Avatar

Level 6

overlay default.jsp under /apps/sling/servlet/errorhandler and added above code, after it was fine. also, I used response.sendError(500) for testing. Not sure why Exception.jsp/Throwable.jsp did not work

Avatar

Level 3
        Thanks Rakesh, a handy example for custom Error Handler Servlet