From 0fe4ff18751156fa072e1f83077e49a8597e7dcd Mon Sep 17 00:00:00 2001 From: =?utf8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Wed, 17 Oct 2018 08:24:45 +0200 Subject: [PATCH] tpl: Improve the Execute panic error message See #5327 --- hugolib/hugo_sites_build_errors_test.go | 12 ++++++++++++ tpl/template.go | 17 ++++++++++++----- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/hugolib/hugo_sites_build_errors_test.go b/hugolib/hugo_sites_build_errors_test.go index 07422075..cf347a2d 100644 --- a/hugolib/hugo_sites_build_errors_test.go +++ b/hugolib/hugo_sites_build_errors_test.go @@ -109,6 +109,18 @@ func TestSiteBuildErrors(t *testing.T) { a.assertLineNumber(2, err) }, },*/ + + { + name: "Panic in template Execute", + fileType: single, + fileFixer: func(content string) string { + return strings.Replace(content, ".Title", ".Parent.Parent.Parent", 1) + }, + assertBuildError: func(a testSiteBuildErrorAsserter, err error) { + assert.Error(err) + assert.Contains(err.Error(), "layouts/_default/single.html") + }, + }, } for _, test := range tests { diff --git a/tpl/template.go b/tpl/template.go index 02b2d4a9..68673a1f 100644 --- a/tpl/template.go +++ b/tpl/template.go @@ -115,8 +115,9 @@ func extractBaseOf(err string) string { func (t *TemplateAdapter) Execute(w io.Writer, data interface{}) (execErr error) { defer func() { // Panics in templates are a little bit too common (nil pointers etc.) + // See https://github.com/gohugoio/hugo/issues/5327 if r := recover(); r != nil { - execErr = t.addFileContext(t.Name(), fmt.Errorf("panic in Execute: %s", r)) + execErr = t.addFileContext(t.Name(), fmt.Errorf(`panic in Execute: %s. See "https://github.com/gohugoio/hugo/issues/5327" for the reason why we cannot provide a better error message for this.`, r)) } }() @@ -152,7 +153,7 @@ func (t *TemplateAdapter) addFileContext(name string, inerr error) error { master, hasMaster := t.NameBaseTemplateName[name] - ferr := errors.Wrapf(inerr, "execute of template %q failed", realFilename) + ferr1 := errors.Wrapf(inerr, "execute of template %q failed", realFilename) // Since this can be a composite of multiple template files (single.html + baseof.html etc.) // we potentially need to look in both -- and cannot rely on line number alone. @@ -175,7 +176,7 @@ func (t *TemplateAdapter) addFileContext(name string, inerr error) error { } // TODO(bep) 2errors text vs HTML - fe, ok := herrors.WithFileContext(ferr, f, "go-html-template", lineMatcher) + fe, ok := herrors.WithFileContext(ferr1, f, "go-html-template", lineMatcher) if ok || !hasMaster { return fe } @@ -187,8 +188,14 @@ func (t *TemplateAdapter) addFileContext(name string, inerr error) error { } defer f.Close() - ferr = errors.Wrapf(inerr, "execute of template %q failed", realFilename) - fe, _ = herrors.WithFileContext(ferr, f, "go-html-template", lineMatcher) + ferr2 := errors.Wrapf(inerr, "execute of template %q failed", realFilename) + fe, ok = herrors.WithFileContext(ferr2, f, "go-html-template", lineMatcher) + + if !ok { + // Return the most specific. + return ferr1 + + } return fe } -- 2.30.2