github.com/gramework/gramework@v1.8.1-0.20231027140105-82555c9057f5/handlePanic.go (about) 1 package gramework 2 3 import "strings" 4 5 var errGotPanic = struct { 6 Code int `json:"code" xml:"code" csv:"code"` 7 Message string `json:"message" xml:"message" csv:"message"` 8 }{ 9 Code: 500, 10 Message: "Internal Server Error", 11 } 12 13 // DefaultPanicHandler serves error page or error response depending on ctx.ContentType() 14 func DefaultPanicHandler(ctx *Context, panicReason interface{}) { 15 ctx.SetStatusCode(500) 16 if strings.HasPrefix(string(ctx.Request.Header.Peek("Accept")), "text/html") || strings.Contains(ctx.ContentType(), "text/html") { 17 _, err := ctx.HTML().WriteString(handledPanic) 18 if err != nil { 19 ctx.Logger.WithError(err).Error("could not serve default panic page") 20 return 21 } 22 if !ctx.App.PanicHandlerNoPoweredBy { 23 if _, err := ctx.WriteString(poweredBy); err != nil { 24 // connection broken 25 ctx.Error("", 500) 26 } 27 } 28 if len(ctx.App.PanicHandlerCustomLayout) > 0 { 29 if _, err := ctx.WriteString(ctx.App.PanicHandlerCustomLayout); err != nil { 30 // connection broken 31 ctx.Error("", 500) 32 } 33 } 34 return 35 } 36 37 if _, err := ctx.Encode(errGotPanic); err != nil { 38 ctx.Error("", 500) 39 } 40 } 41 42 const handledPanic = `<!doctype html> 43 <html> 44 <meta charset=utf-8> 45 <meta name=viewport content="width=device-width,initial-scale=1"> 46 <title>Internal Server Error</title> 47 <meta http-equiv="Content-Security-Policy" content="default-src 'none'; base-uri 'self'; connect-src 'self'; form-action 'self'; img-src 'self' data:; script-src 'self'; style-src 'unsafe-inline'"> 48 <style> 49 html { 50 position: relative; 51 font-family: sans-serif; 52 -webkit-font-smoothing: subpixel-antialiased; 53 text-rendering: optimizeLegibility; 54 } 55 body, html, 56 .mainWrapper { 57 height: 100%; 58 width: 100%; 59 margin: 0; 60 padding: 0; 61 } 62 .mainWrapper { 63 background: #000; 64 background-image: 65 linear-gradient( 66 0deg, 67 rgba(0,0,0,0) 24%, 68 rgba(255,255,255,.05) 25%, 69 rgba(255,255,255,.05) 26%, 70 rgba(0,0,0,0) 27%, 71 rgba(0,0,0,0) 74%, 72 rgba(255,255,255,.05) 75%, 73 rgba(255,255,255,.05) 76%, 74 rgba(0,0,0,0) 77%, 75 rgba(0,0,0,0) 76 ), 77 linear-gradient( 78 90deg, 79 rgba(0,0,0,0) 24%, 80 rgba(255,255,255,.05) 25%, 81 rgba(255,255,255,.05) 26%, 82 rgba(0,0,0,0) 27%, 83 rgba(0,0,0,0) 74%, 84 rgba(255,255,255,.05) 75%, 85 rgba(255,255,255,.05) 76%, 86 rgba(0,0,0,0) 77%, 87 rgba(0,0,0,0) 88 ); 89 background-size: 25px 25px; 90 background-position: left 30px top 31px; 91 display: flex; 92 align-items: center; 93 justify-content: center; 94 flex-direction: column; 95 } 96 h1 { 97 color: #1e2c7f; 98 color: #fafafa; 99 font-size: 72px; 100 margin-top: 0; 101 } 102 p { 103 margin: 0; 104 } 105 div { 106 color: #fff; 107 } 108 .poweredBy { 109 position: absolute; 110 opacity: .65; 111 width: 100%; 112 bottom: 0; 113 text-align: center; 114 font-size: 10px; 115 } 116 a { 117 font-weight: bold; 118 color: #fff !important; 119 } 120 .poweredBy p { 121 padding: 10px; 122 } 123 </style> 124 <div class="mainWrapper"> 125 <h1>500</h1> 126 <p>Sorry, our service is currently unavailable.</p> 127 <p>Wait a minute and try again.</p> 128 </div> 129 ` 130 131 const poweredBy = `<div class="poweredBy"> 132 <p>Powered by <a target=_blank href="https://github.com/gramework/gramework">Gramework</a>.</p> 133 </div>`