How to get the message in a custom error page (Tomcat)?
Asked Answered
M

7

28

In JSPs, you may use response.sendError(int code, String message) to return a particular error code (eg 404 for not found) and a message as well. These messages display fine, as long as you use the default ugly Tomcat error pages. However, if you create a custom error page, how do you get that message? I've tried exception.getMessage() or pageContext.getErrorData() but no avail. I've been searching for this for like hours and nobody seems to even wonder about the same thing! :S

I forgot to mention I've only tried it with 404s so far, since that's what I need most... The exception is null for some reason, so trying anything on it throws a NullPointerException. The error page is a 404 error page, set via web.xml (since I want it to be displayed for EVERY single 404 error) and for anyone wondering, yes it has the isErrorPage directive set to true...

Marlite answered 15/6, 2009 at 9:46 Comment(5)
Does your custom 404 page never work? How do you check if it works? Have you check if the below by me mentioned request attributes exist? Last resort try this tutorial playground.greyscale.se/wiki/en/Custom_404_page_in_TomcatConspectus
No it works fine. I just don't know how to get the message, if set via response.sendError().Marlite
response.sendError() will send error to your clients browser. It will not go to your error page after that unless you will do it yourself I think.Sphere
Nope, it displays the custom error page just fine, as long as you properly set it via web.xml :) The only thing is that I don't know how to get the error message, if set.Marlite
I found this: #1104952Apposition
S
14

The error message is available via javax.servlet.error.message attribute of the request object in error page jsp.

Here is the jsp syntax to access it:

<c:out value="${requestScope['javax.servlet.error.message']}"/>

You could look for other error related information available in the error page here under New Error Attributes.

Shellieshellproof answered 23/6, 2009 at 19:31 Comment(2)
It should according to the spec and it actually does in our Tomcat based application. You may have some weird configuration issue. Anyhow, good luck on that one, and would be great to know the solution at the end.Shellieshellproof
@Lea Verou: It does work. Probably you didn't have jstl enabled in your application so the c:out tag was printed on HTML which you never saw as rendered output.Lexical
C
9

Hmm exception.getMessage() should work

Try adding exception.getClass().getName()

  1. It could be a NullPointerException which has no message
  2. or the exception is not from Sun and the message isn't set properly

Of course this only works, if I remember correctly, if the error is thrown by a jsp with <%@ page errorPage="/yourerrorpage.jsp" %> at the top.

If the error comes from a servlet the exception details are passed as request attributes

javax.servlet.error.status_code    java.lang.Integer
javax.servlet.error.exception_type java.lang.Class
javax.servlet.error.message        java.lang.String
javax.servlet.error.exception      java.lang.Throwable
javax.servlet.error.request_uri    java.lang.String
javax.servlet.error.servlet_name   java.lang.String

Check the Servlet Specification (link is broken since ~2011) section 9.9

Conspectus answered 15/6, 2009 at 9:53 Comment(2)
Instead of using the the provided strings for request attributes directly, one should use the constants defined in RequestDispatcher, e.g. RequestDispatcher.ERROR_EXCEPTION.Dermatoid
<%@ page language="java" contentType="application/json; charset=UTF-8" pageEncoding="UTF-8" isErrorPage="true"%><%out.println( request.getAttribute("javax.servlet.error.message") );%>Gwendolin
C
5

I'm sorry for answering so late, but I faced with this problem just a week ago, I've browsed a lot of different sites but nobody really aswered this problem the way I wanted to hear. In this post I found out a few interesting solutions and then came up to my own. Just include this source in your page:

<%
    out.println(pageContext.getErrorData().getRequestURI());
    out.println("<br/>");
    out.println(pageContext.getErrorData().getStatusCode());
    out.println("<br/>");
    out.println(pageContext.getException());
    out.println("<br/>");
%>

It worked perfectly fine with me.

Compilation answered 19/4, 2013 at 2:35 Comment(0)
S
0

The thing you want looks weird to me :). That said, I would do the following:

  1. Implement HttpResponseWrapper to wrap any other HttpResponse in this way:

    public class HttpResponseWrapper implements HttpResponse {
        private String errorMessage;
    ...
    
        @Override
        public void sendError(...) {
            <save error message here>
        }
    ...
    }
    
  2. Create a Filter and wrap any response in this

  3. Put filter on all requests and first in the chain

  4. In your error page check if response is instanceof HttpResponseWrapper

  5. Get your message

Sphere answered 15/6, 2009 at 22:9 Comment(2)
Thanks for your time, but did you actually read my post? I have set isErrorPage to true, and my 404 works fine (which means I've already done it right in web.xml, so there's no need to mention the error-page tag). I also mentioned that my question is about 404s, not exceptions.Marlite
Yep, my fault. Somehow missed the point of the question. Happens. Updating my answerSphere
R
0

The exception part of the ErrorData will only be set if the error page was loaded as a result of an exception and not a response error code.

See the javadoc for sendError on HttpServletResponse. It mentions why you're not seeing the message you passed to sendError (emphasis mine):

Sends an error response to the client using the specified status. The server defaults to creating the response to look like an HTML-formatted server error page containing the specified message, setting the content type to "text/html", leaving cookies and other headers unmodified. If an error-page declaration has been made for the web application corresponding to the status code passed in, it will be served back in preference to the suggested msg parameter.

If the response has already been committed, this method throws an IllegalStateException. After using this method, the response should be considered to be committed and should not be written to.

Rinee answered 22/6, 2009 at 18:15 Comment(1)
Thanks. I had read that previously, but hadn't noticed the part you emphasized. So, to cut a long story short, it's not possible at all? :-(Marlite
T
0

You can use

${requestScope['javax.servlet.error.message']}

if you don't have jstl on the page

Thumping answered 25/12, 2016 at 6:20 Comment(0)
R
0
<%
    if (null != request.getAttribute("errorMessage")) {
       out.println(request.getAttribute("errorMessage"));
    }
%>

You can use

Rose answered 24/2, 2023 at 4:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.