aboutsummaryrefslogtreecommitdiffstats
path: root/modules/context
diff options
context:
space:
mode:
authorzeripath <art27@cantab.net>2023-03-20 20:56:48 +0000
committerGitHub <noreply@github.com>2023-03-20 15:56:48 -0500
commit8f3aaef3747e8c656cfe2562996dc1806b4d8a0f (patch)
treeb5bd7187bcaee6b7d47d9250a1c947a2fa4057e8 /modules/context
parent529bac1950adf4fb72433cb67f66b0eec49224fe (diff)
downloadgitea-8f3aaef3747e8c656cfe2562996dc1806b4d8a0f.tar.gz
gitea-8f3aaef3747e8c656cfe2562996dc1806b4d8a0f.zip
Improve template error reporting (#23396)
There are multiple duplicate reports of errors during template rendering due to broken custom templates. Unfortunately the error returned here is somewhat difficult for users to understand and it doesn't return the context of the error. This PR attempts to parse the error returned by the template renderer to add in some further context including the filename of the template AND the preceding lines within that template file. Ref #23274 --------- Signed-off-by: Andrew Thornton <art27@cantab.net>
Diffstat (limited to 'modules/context')
-rw-r--r--modules/context/context.go32
1 files changed, 32 insertions, 0 deletions
diff --git a/modules/context/context.go b/modules/context/context.go
index 50c34edae2..5876e23cc4 100644
--- a/modules/context/context.go
+++ b/modules/context/context.go
@@ -16,8 +16,10 @@ import (
"net/http"
"net/url"
"path"
+ "regexp"
"strconv"
"strings"
+ texttemplate "text/template"
"time"
"code.gitea.io/gitea/models/db"
@@ -213,6 +215,8 @@ func (ctx *Context) RedirectToFirst(location ...string) {
ctx.Redirect(setting.AppSubURL + "/")
}
+var templateExecutingErr = regexp.MustCompile(`^template: (.*):([1-9][0-9]*):([1-9][0-9]*): executing (?:"(.*)" at <(.*)>: )?`)
+
// HTML calls Context.HTML and renders the template to HTTP response
func (ctx *Context) HTML(status int, name base.TplName) {
log.Debug("Template: %s", name)
@@ -228,6 +232,34 @@ func (ctx *Context) HTML(status int, name base.TplName) {
ctx.PlainText(http.StatusInternalServerError, "Unable to find status/500 template")
return
}
+ if execErr, ok := err.(texttemplate.ExecError); ok {
+ if groups := templateExecutingErr.FindStringSubmatch(err.Error()); len(groups) > 0 {
+ errorTemplateName, lineStr, posStr := groups[1], groups[2], groups[3]
+ target := ""
+ if len(groups) == 6 {
+ target = groups[5]
+ }
+ line, _ := strconv.Atoi(lineStr) // Cannot error out as groups[2] is [1-9][0-9]*
+ pos, _ := strconv.Atoi(posStr) // Cannot error out as groups[3] is [1-9][0-9]*
+ filename, filenameErr := templates.GetAssetFilename("templates/" + errorTemplateName + ".tmpl")
+ if filenameErr != nil {
+ filename = "(template) " + errorTemplateName
+ }
+ if errorTemplateName != string(name) {
+ filename += " (subtemplate of " + string(name) + ")"
+ }
+ err = fmt.Errorf("%w\nin template file %s:\n%s", err, filename, templates.GetLineFromTemplate(errorTemplateName, line, target, pos))
+ } else {
+ filename, filenameErr := templates.GetAssetFilename("templates/" + execErr.Name + ".tmpl")
+ if filenameErr != nil {
+ filename = "(template) " + execErr.Name
+ }
+ if execErr.Name != string(name) {
+ filename += " (subtemplate of " + string(name) + ")"
+ }
+ err = fmt.Errorf("%w\nin template file %s", err, filename)
+ }
+ }
ctx.ServerError("Render failed", err)
}
}