Win a copy of Murach's Python Programming this week in the Jython/Python forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Error logging/notification question  RSS feed

 
Rick Crawford
Ranch Hand
Posts: 34
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello all. As per usual, I'm not sure this is the right spot for my question. But I thought I'd try it here first.
I'm trying to develop a generic error handling/notification system for a website. My idea is to trap certain errors, such as an HTTP 500 error code and email the webmaster with the details. I have experimented with modifying my web.xml file and sucessfully forwarded to specific .jsp page when an error occurs.
To assist the programmer in fixing the error, I would like to include in the message the parameters, if any, that were entered by the user that caused the error. I was sort of using the famous "SnoopServlet.java" program as a reference. I pretty much 'gutted' SnoopServlet and placed it into an errorhandling .jsp which I've called "Error500.jsp".
What I'm stuck on is, how do I reference within my error handling page the URL where the error actually occurred, as well as all the request.getParameter()'s that the user typed in? It seems that when the error page fires, the code I've stripped out of SnoopServlet reports only information pertaining to my error page. For example, this line from SnoopServlet:
out.println (HttpUtils.getRequestURL (request).toString ());
..prints this message:
http://localhost/Error500.jsp
Instead of the page where the error occurred:
http://localhost/GenerateError.jsp
Any ideas?
Thanks,
Rick
 
Gerry Giese
Ranch Hand
Posts: 247
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rick,
Two things we could use to help out would be a copy of the forwarding code snippet, and detail on what server(s) you're using to run the servlets. I use Resin, which is awesome, esp for development. They allow handling of errors this way:
* http://www.caucho.com/products/resin/ref/app-config.xtp#error-page
* http://www.caucho.com/products/resin/faq/servlet.xtp (see "How do I print an exception stack trace to the JSP out?")
* http://www.caucho.com/products/resin/faq/debug.xtp
As for storing the actual request URL & misc, my suggestion is capture it (and whatever other Exception data you need) wherever the exception is caught, pack it into a Hashtable, put that into the request using setAttribute(), and *then* forward it. Your handler JSP then unpacks the Hashtable and reads the data and deals with it.
I'm not familiar with SnoopServlet, but you're example sounds confusing. Are you calling SnoopServlet, forwarding to GeneratorError.jsp, then forwarding to Error500.jsp?? Or is the "out.println(...)" you list occur in one of the jsp's instead of SnoopServlet? Posting your actual in-use code would be helpful.
Cheers,
Gerry
 
Rick Crawford
Ranch Hand
Posts: 34
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the response. My development web server is JRun, my production web server is Tomcat. To restate what I'm trying to achieve, I want to trap 500-type errors in jsp/servlets, then log or email the relevant data (script or servlet where the error occured, data entered by the user, etc.) to someone who might be able fix the error.
As a means to get me to this end, I found some documentation that describes a method of adding an error handling directive to a file called web.xml. Here is an abbreviated version of what my web.xml looks like with this error trapping mechanism in place:

What this is supposed to do is intercept any HTTP 500's and forward the user to a specified page. This appears to work, at least the forwarding does. To test the theory, I wrote this little pre-broken .jsp called GenerateError.jsp that quickly
generates a 500 error:

Then in my first permutation of Error500.jsp, I placed this code:

When I ran the test, I saw the message I had placed in Error500.jsp. So far so good. Now I wanted to take this
experiment to the next level. I wanted to capture the requested URL where the error occurred (http://localhost/GenerateError.jsp) as well as any form data (like the parms in a querystring) that were entered by the user. Once I had this information captured, I would log the data and/or send myself an email notification with the information that an error had occurred.
Sun has written a little test servlet called SnoopServlet that is supplied with JRun and Tomcat. It is just a little novelty
program to test a web server's connectivity. It simply echoes back the request line and headers that were sent in from the client. As I stated, I figured I could 'gut' out the sections of the code that display the URL location and the request line and use it within my Error500.jsp script. Here is the section of code that is supposed to echo out the requested URL:

The problem is that this code prints this message: http://localhost/Error500.jsp
Instead of the page where the error actually occurred, which is what I need to track down and fix the problem: http://localhost/GenerateError.jsp
Although I can get the forwarding and the email notification to work, It appears that my approach to retrieving the URL where the error occurred and the logging the querystring isn't going to work.
Sorry for the length of this message. I very much appreciate any assistance.
Thanks again,
Rick <><

[This message has been edited by Rick Crawford (edited November 27, 2001).]
 
Mike Curwen
Ranch Hand
Posts: 3695
IntelliJ IDE Java Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't have a solution for retrieving the request URL of the page that throws an error. I suspect this might not be possible. When you specify in a JSP, that the errorPage="error.jsp", then the container will call that page for you. So in a very real sense, the request object should report the errorPage, and not the page that throws the error.

I have used the following code to help me:When I'm in development mode, I leave the bottom <% %> tags as is. But on a deployed site, I might surround them with HTML comments, so the stack trace is invisible.

This answer at least *part* of your question. The top line of the stack trace will contain the jsp page (and line number) where the error occured.
 
Gerry Giese
Ranch Hand
Posts: 247
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rick,
This is just my initial thinking, and maybe somebody can back me up, but I think you're half right but half wrong. Forwarding to a 500.jsp so you can get an email or other notification is probably a good thing, but you should rely on the original page/servlet to catch the error and log it. Does your server log give you an error message or stack trace when it hits GenerateError.jsp's bad line? If so, that's all you need. The 500.jsp should report that an error occured at X date/time, and then you just go check the log. If you are doing something like a request.getParameter() you should be doing error-checking before you use the variable anyway, either looking for null (preferred) or doing try/catch.
BTW, my guess is your servlet containers are generating a new request for the 500.jsp, rather than forwarding the request that generated the error.
Anyway, check your logs to see if GenerateError.jsp is printing anything when it dies. If it does, and you use the method I suggested above, then when you get notified of an error and you can't determine the error from the stack trace and code appropriate error-condition checking into the JSP, just modify the JSP to log the request URL every time it gets hit until the error manifests again, then going by the date/time you get the next notification you can do more in-depth debugging.
There's no substitute for defensive programming.
Cya!
 
Gerry Giese
Ranch Hand
Posts: 247
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Was reading on JSPs (Special Edition Using Java Server Pages and Servlets - great book!) and came across this - there are two "page" directives you can use to handle errors, 1) in GenerateError.jsp have <@ page errorPage="500.jsp" %>, and 2) in 500.jsp have <%@ page isErrorPage="true"%> and refer to <%= exception.getMessage() %>.
The exception in 500.jsp is the Throwable created by GenerateError.jsp. The author warns that JSP engines may flush buffers and screw up this process if you're using included JSPs in your page that referes to errorPage= in it, so do your includes after the error-prone section, or don't use includes. Sounds like just what you were wanting.
 
Rick Crawford
Ranch Hand
Posts: 34
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As always, this list has been a tremendous help. I'm going to follow up on some of these suggestions to see what will work best.
Gerry: it sounds like the last thing you suggested would probably work great for what I'm trying to accomplish.
Thanks to all!
Rick <><
 
Gerry Giese
Ranch Hand
Posts: 247
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rick - found the following in an article on JavaWorld, thought it might be useful:
http://www.javaworld.com/javaworld/jw-11-2001/jw-1130-jsp_p.html
http://java.sun.com/products/jsp/html/exceptions.fm.html - read this!
Exception information is more useful if information besides the stack trace is included. JSPs can use session variables to store information about the current page and current operation being performed. Then, if an exception does occur, the exception page will be called; it will have access to both the thrown exception and the information about the original page that caused the exception. The exception page can utilize underlying Java code, in JavaBeans or EJBs, to store in the database the complete exception information, related session information, and the exception's date and time.
[This message has been edited by Gerry Giese (edited December 05, 2001).]
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!