code.gitea.io/gitea@v1.21.7/routers/common/errpage.go (about) 1 // Copyright 2023 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package common 5 6 import ( 7 "fmt" 8 "net/http" 9 10 user_model "code.gitea.io/gitea/models/user" 11 "code.gitea.io/gitea/modules/base" 12 "code.gitea.io/gitea/modules/context" 13 "code.gitea.io/gitea/modules/httpcache" 14 "code.gitea.io/gitea/modules/log" 15 "code.gitea.io/gitea/modules/setting" 16 "code.gitea.io/gitea/modules/templates" 17 "code.gitea.io/gitea/modules/web/middleware" 18 "code.gitea.io/gitea/modules/web/routing" 19 ) 20 21 const tplStatus500 base.TplName = "status/500" 22 23 // RenderPanicErrorPage renders a 500 page, and it never panics 24 func RenderPanicErrorPage(w http.ResponseWriter, req *http.Request, err any) { 25 combinedErr := fmt.Sprintf("%v\n%s", err, log.Stack(2)) 26 log.Error("PANIC: %s", combinedErr) 27 28 defer func() { 29 if err := recover(); err != nil { 30 log.Error("Panic occurs again when rendering error page: %v. Stack:\n%s", err, log.Stack(2)) 31 } 32 }() 33 34 routing.UpdatePanicError(req.Context(), err) 35 36 httpcache.SetCacheControlInHeader(w.Header(), 0, "no-transform") 37 w.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions) 38 39 tmplCtx := context.TemplateContext{} 40 tmplCtx["Locale"] = middleware.Locale(w, req) 41 ctxData := middleware.GetContextData(req.Context()) 42 43 // This recovery handler could be called without Gitea's web context, so we shouldn't touch that context too much. 44 // Otherwise, the 500-page may cause new panics, eg: cache.GetContextWithData, it makes the developer&users couldn't find the original panic. 45 user, _ := ctxData[middleware.ContextDataKeySignedUser].(*user_model.User) 46 if !setting.IsProd || (user != nil && user.IsAdmin) { 47 ctxData["ErrorMsg"] = "PANIC: " + combinedErr 48 } 49 50 err = templates.HTMLRenderer().HTML(w, http.StatusInternalServerError, string(tplStatus500), ctxData, tmplCtx) 51 if err != nil { 52 log.Error("Error occurs again when rendering error page: %v", err) 53 w.WriteHeader(http.StatusInternalServerError) 54 _, _ = w.Write([]byte("Internal server error, please collect error logs and report to Gitea issue tracker")) 55 } 56 }