Added a sysconfig variable for global error debugging in ErrorHandler.
[jsvc.git] / src / dolda / jsvc / util / ErrorHandler.java
1 package dolda.jsvc.util;
2
3 import dolda.jsvc.*;
4 import java.net.*;
5 import java.io.*;
6 import java.util.logging.*;
7
8 public class ErrorHandler implements Responder {
9     private Responder next;
10     private static Logger logger = Logger.getLogger("dolda.jsvc.context");
11     
12     public ErrorHandler(Responder next) {
13         this.next = next;
14     }
15     
16     protected void log(Request req, Throwable t) {
17         logger.log(Level.SEVERE, "Unhandled error in responder", t);
18     }
19     
20     protected void respdebug(Request req, Throwable t) {
21         req.status(500);
22         req.outheaders().put("content-type", "text/plain; charset=utf-8");
23         PrintWriter out;
24         try {
25             out = new PrintWriter(new OutputStreamWriter(req.output(), "UTF-8"));
26         } catch(UnsupportedEncodingException e) {
27             throw(new Error(e));
28         }
29         t.printStackTrace(out);
30         out.flush();
31     }
32     
33     protected void resperr(Request req, Throwable t) {
34         req.status(500);
35         req.outheaders().put("content-type", "text/html; charset=us-ascii");
36         PrintWriter out;
37         try {
38             out = new PrintWriter(new OutputStreamWriter(req.output(), "US-ASCII"));
39         } catch(UnsupportedEncodingException e) {
40             throw(new Error(e));
41         }
42         out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
43         out.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">");
44         out.println("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en-US\">");
45         out.println("<head><title>Internal error</title></head>");
46         out.println("<body>");
47         out.println("<h1>Internal error</h1>");
48         out.println("An error occurred on the server processing your request.");
49         out.println("</body>");
50         out.println("</html>");
51         out.flush();
52     }
53     
54     protected boolean debug(Request req, Throwable t) {
55         ThreadContext thc = ThreadContext.current();
56         if(thc != null) {
57             if(Misc.boolval(thc.server().sysconfig("jsvc.debug-errors", "0")))
58                 return(true);
59         }
60         SocketAddress rem = req.remoteaddr();
61         return((rem instanceof InetSocketAddress) && ((InetSocketAddress)rem).getAddress().isLoopbackAddress());
62     }
63
64     protected void handle(Request req, Throwable t) {
65         log(req, t);
66         if(req instanceof ResettableRequest) {
67             ResettableRequest rr = (ResettableRequest)req;
68             if(rr.canreset())
69                 rr.reset();
70         }
71         if(debug(req, t))
72             respdebug(req, t);
73         else
74             resperr(req, t);
75     }
76     
77     public void respond(Request req) {
78         try {
79             next.respond(req);
80         } catch(Throwable t) {
81             handle(req, t);
82         }
83     }
84 }