From 8d42a7942ad2cc3ecff2ad90502c7e9e87da5d52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Thu, 1 Feb 2024 16:35:41 +0100 Subject: [PATCH] Improve nilpointer error message --- common/herrors/errors.go | 21 +++++++++++++++++++++ hugolib/paginator_test.go | 12 ++++++++++++ hugolib/site_render.go | 3 ++- 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/common/herrors/errors.go b/common/herrors/errors.go index 59739a86a..7c389c1ae 100644 --- a/common/herrors/errors.go +++ b/common/herrors/errors.go @@ -19,8 +19,10 @@ import ( "fmt" "io" "os" + "regexp" "runtime" "runtime/debug" + "strings" "time" ) @@ -116,3 +118,22 @@ func IsNotExist(err error) bool { return false } + +var nilPointerErrRe = regexp.MustCompile(`at <(.*)>: error calling (.*?): runtime error: invalid memory address or nil pointer dereference`) + +func ImproveIfNilPointer(inErr error) (outErr error) { + outErr = inErr + + m := nilPointerErrRe.FindStringSubmatch(inErr.Error()) + if len(m) == 0 { + return + } + call := m[1] + field := m[2] + parts := strings.Split(call, ".") + receiverName := parts[len(parts)-2] + receiver := strings.Join(parts[:len(parts)-1], ".") + s := fmt.Sprintf("– %s is nil; wrap it in if or with: {{ with %s }}{{ .%s }}{{ end }}", receiverName, receiver, field) + outErr = errors.New(nilPointerErrRe.ReplaceAllString(inErr.Error(), s)) + return +} diff --git a/hugolib/paginator_test.go b/hugolib/paginator_test.go index 2ce07805e..fb592bed1 100644 --- a/hugolib/paginator_test.go +++ b/hugolib/paginator_test.go @@ -170,3 +170,15 @@ Paginator: {{ .Paginator }} b.Assert(err, qt.IsNotNil) b.Assert(err.Error(), qt.Contains, `error calling Paginator: pagination not supported for this page: kind: "page"`) } + +func TestNilPointerErrorMessage(t *testing.T) { + files := ` +-- hugo.toml -- +-- content/p1.md -- +-- layouts/_default/single.html -- +Home Filename: {{ site.Home.File.Filename }} +` + b, err := TestE(t, files) + b.Assert(err, qt.IsNotNil) + b.Assert(err.Error(), qt.Contains, `_default/single.html:1:22: executing "_default/single.html" – File is nil; wrap it in if or with: {{ with site.Home.File }}{{ .Filename }}{{ end }}`) +} diff --git a/hugolib/site_render.go b/hugolib/site_render.go index 138530680..ef3e3aeef 100644 --- a/hugolib/site_render.go +++ b/hugolib/site_render.go @@ -20,6 +20,7 @@ import ( "strings" "sync" + "github.com/gohugoio/hugo/common/herrors" "github.com/gohugoio/hugo/hugolib/doctree" "github.com/gohugoio/hugo/config" @@ -110,7 +111,7 @@ func (s *Site) renderPages(ctx *siteRenderContext) error { err := <-errs if err != nil { - return fmt.Errorf("failed to render pages: %w", err) + return fmt.Errorf("failed to render pages: %w", herrors.ImproveIfNilPointer(err)) } return nil }