1 module hunt.http.routing.handler.ErrorResponseHandler; 2 3 import hunt.http.routing.handler.DefaultErrorResponseHandler; 4 import hunt.http.routing.RoutingContext; 5 6 import hunt.http.Version; 7 import hunt.http.HttpHeader; 8 import hunt.http.HttpStatus; 9 10 import hunt.logging; 11 import hunt.Exceptions; 12 13 import std.conv; 14 import std.concurrency : initOnce; 15 import std.range; 16 17 18 /** 19 * 20 */ 21 abstract class ErrorResponseHandler : RouteHandler { 22 23 private __gshared ErrorResponseHandler inst; 24 25 static ErrorResponseHandler Default() { 26 if(inst is null) { 27 inst = new DefaultErrorResponseHandler(); 28 } 29 return inst; 30 } 31 32 static void Default(ErrorResponseHandler handler) { 33 inst = handler; 34 } 35 36 private int _status; 37 38 this(int status = HttpStatus.NOT_FOUND_404) { 39 _status = status; 40 } 41 42 43 void handle(RoutingContext context) { 44 if (context.hasNext()) { 45 try { 46 context.next(); 47 } catch (Exception t) { 48 version(HUNT_DEBUG) errorf("http handler exception", t.msg); 49 if (!context.isCommitted()) { 50 render(context, HttpStatus.INTERNAL_SERVER_ERROR_500, t); 51 context.fail(t); 52 } 53 } 54 } else { 55 render(context, _status, null); 56 context.succeed(true); 57 } 58 } 59 60 abstract void render(RoutingContext context, int status, Exception ex); 61 } 62 63 64 void renderErrorPage(RoutingContext context, int status, Exception t) { 65 HttpStatusCode code = HttpStatus.getCode(status); 66 if(code == HttpStatusCode.Null) 67 code = HttpStatusCode.INTERNAL_SERVER_ERROR; 68 69 string title = status.to!string() ~ " " ~ code.getMessage(); 70 string content; 71 if(status == HttpStatus.NOT_FOUND_404) { 72 // content = title; 73 } else if(status == HttpStatus.INTERNAL_SERVER_ERROR_500) { 74 content = "The server internal error. <br/>" ~ (t !is null ? t.msg : ""); 75 } else { 76 content = (t !is null ? t.msg : ""); 77 } 78 79 context.setStatus(status); 80 context.getResponseHeaders().put(HttpHeader.CONTENT_TYPE, "text/html"); 81 context.write("<!DOCTYPE html>") 82 .write("<html>") 83 .write("<head>") 84 .write("<title>") 85 .write(title) 86 .write("</title>") 87 .write("</head>") 88 .write("<body>") 89 .write("<center><h1> " ~ title ~ " </h1></center>"); 90 91 if(!content.empty()) { 92 context.write("<center><p>" ~ content ~ "</p></center>"); 93 } 94 95 context.write("<hr/>") 96 .write("<center><footer><em>powered by Hunt HTTP " ~ Version ~"</em></footer></center>") 97 .write("</body>") 98 .end("</html>"); 99 } 100 101