From a7d2eb2686c6e87d97d66051ba577178e5432511 Mon Sep 17 00:00:00 2001 From: Fredrik Tolf Date: Tue, 13 Oct 2009 00:01:59 +0200 Subject: [PATCH] Added a general-purpose root error handler. --- src/dolda/jsvc/test/Bootstrap.java | 3 +- src/dolda/jsvc/test/TestResponder.java | 6 +++ src/dolda/jsvc/util/ErrorHandler.java | 79 ++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 src/dolda/jsvc/util/ErrorHandler.java diff --git a/src/dolda/jsvc/test/Bootstrap.java b/src/dolda/jsvc/test/Bootstrap.java index 49abdd2..bb72f30 100644 --- a/src/dolda/jsvc/test/Bootstrap.java +++ b/src/dolda/jsvc/test/Bootstrap.java @@ -1,9 +1,10 @@ package dolda.jsvc.test; import dolda.jsvc.*; +import dolda.jsvc.util.*; public class Bootstrap { public static Responder responder() { - return(new TestResponder()); + return(new ErrorHandler(new TestResponder())); } } diff --git a/src/dolda/jsvc/test/TestResponder.java b/src/dolda/jsvc/test/TestResponder.java index d7541b4..414dfef 100644 --- a/src/dolda/jsvc/test/TestResponder.java +++ b/src/dolda/jsvc/test/TestResponder.java @@ -13,6 +13,9 @@ public class TestResponder implements Responder { throw(new Error(e)); } + if(req.path().equals("bard1")) + throw(new RuntimeException("bard1")); + out.println(""); out.println("Barda"); out.println(""); @@ -23,6 +26,9 @@ public class TestResponder implements Responder { out.println(req.remoteaddr() + "<->" + req.localaddr()); out.println(""); out.println(""); + + if(req.path().equals("bard2")) + throw(new RuntimeException("bard2")); out.flush(); } } diff --git a/src/dolda/jsvc/util/ErrorHandler.java b/src/dolda/jsvc/util/ErrorHandler.java new file mode 100644 index 0000000..f1149e8 --- /dev/null +++ b/src/dolda/jsvc/util/ErrorHandler.java @@ -0,0 +1,79 @@ +package dolda.jsvc.util; + +import dolda.jsvc.*; +import java.net.*; +import java.io.*; +import java.util.logging.*; + +public class ErrorHandler implements Responder { + private Responder next; + private static Logger logger = Logger.getLogger("jsvc.error"); + + public ErrorHandler(Responder next) { + this.next = next; + } + + protected void log(Request req, Throwable t) { + logger.log(Level.SEVERE, "Unhandled error in responder", t); + } + + protected void respdebug(Request req, Throwable t) { + req.status(500); + req.outheaders().put("content-type", "text/plain; charset=utf-8"); + PrintWriter out; + try { + out = new PrintWriter(new OutputStreamWriter(req.output(), "UTF-8")); + } catch(UnsupportedEncodingException e) { + throw(new Error(e)); + } + t.printStackTrace(out); + out.flush(); + } + + protected void resperr(Request req, Throwable t) { + req.status(500); + req.outheaders().put("content-type", "text/html; charset=us-ascii"); + PrintWriter out; + try { + out = new PrintWriter(new OutputStreamWriter(req.output(), "US-ASCII")); + } catch(UnsupportedEncodingException e) { + throw(new Error(e)); + } + out.println(""); + out.println(""); + out.println(""); + out.println("Internal error"); + out.println(""); + out.println("

Internal error

"); + out.println("An error occurred on the server processing your request."); + out.println(""); + out.println(""); + out.flush(); + } + + protected boolean debug(Request req, Throwable t) { + SocketAddress rem = req.remoteaddr(); + return((rem instanceof InetSocketAddress) && ((InetSocketAddress)rem).getAddress().isLoopbackAddress()); + } + + protected void handle(Request req, Throwable t) { + log(req, t); + if(req instanceof ResettableRequest) { + ResettableRequest rr = (ResettableRequest)req; + if(rr.canreset()) + rr.reset(); + } + if(debug(req, t)) + respdebug(req, t); + else + resperr(req, t); + } + + public void respond(Request req) { + try { + next.respond(req); + } catch(Throwable t) { + handle(req, t); + } + } +} -- 2.11.0