summaryrefslogtreecommitdiffstats
path: root/hugolib
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2022-05-02 16:07:52 +0200
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2022-05-06 19:43:22 +0200
commitf2946da9e806c2bafbdd26707fe339db79bd980b (patch)
treeb5609317a861ea5f399e094e1b9287ca71dc22d1 /hugolib
parent6eea32bd6bc8e7a7dd07a8cb6a8343ae2c74aba0 (diff)
Improve error messages, esp. when the server is running
* Add file context to minifier errors when publishing * Misc fixes (see issues) * Allow custom server error template in layouts/server/error.html To get to this, this commit also cleans up and simplifies the code surrounding errors and files. This also removes the usage of `github.com/pkg/errors`, mostly because of https://github.com/pkg/errors/issues/223 -- but also because most of this is now built-in to Go. Fixes #9852 Fixes #9857 Fixes #9863
Diffstat (limited to 'hugolib')
-rw-r--r--hugolib/config.go5
-rw-r--r--hugolib/configdir_test.go2
-rw-r--r--hugolib/content_factory.go10
-rw-r--r--hugolib/content_map.go3
-rw-r--r--hugolib/content_map_page.go7
-rw-r--r--hugolib/fileInfo.go5
-rw-r--r--hugolib/filesystems/basefs.go10
-rw-r--r--hugolib/hugo_sites.go39
-rw-r--r--hugolib/hugo_sites_build.go10
-rw-r--r--hugolib/hugo_sites_build_errors_test.go108
-rw-r--r--hugolib/integrationtest_builder.go3
-rw-r--r--hugolib/page.go78
-rw-r--r--hugolib/page__meta.go3
-rw-r--r--hugolib/page__per_output.go7
-rw-r--r--hugolib/page__ref.go5
-rw-r--r--hugolib/page_unwrap.go4
-rw-r--r--hugolib/pages_process.go3
-rw-r--r--hugolib/paths/paths.go3
-rw-r--r--hugolib/shortcode.go31
-rw-r--r--hugolib/shortcode_test.go4
-rw-r--r--hugolib/site.go14
-rw-r--r--hugolib/site_render.go5
-rw-r--r--hugolib/testhelpers_test.go10
23 files changed, 226 insertions, 143 deletions
diff --git a/hugolib/config.go b/hugolib/config.go
index 5d2c6ddf7..b2713758a 100644
--- a/hugolib/config.go
+++ b/hugolib/config.go
@@ -33,11 +33,12 @@ import (
"github.com/gohugoio/hugo/parser/metadecoders"
+ "errors"
+
"github.com/gohugoio/hugo/common/herrors"
"github.com/gohugoio/hugo/common/hugo"
"github.com/gohugoio/hugo/langs"
"github.com/gohugoio/hugo/modules"
- "github.com/pkg/errors"
"github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/config/privacy"
@@ -510,5 +511,5 @@ func (configLoader) loadSiteConfig(cfg config.Provider) (scfg SiteConfig, err er
}
func (l configLoader) wrapFileError(err error, filename string) error {
- return herrors.WithFileContextForFileDefault(err, filename, l.Fs)
+ return herrors.NewFileErrorFromFile(err, filename, filename, l.Fs, herrors.SimpleLineMatcher)
}
diff --git a/hugolib/configdir_test.go b/hugolib/configdir_test.go
index 998010318..7ac3f969d 100644
--- a/hugolib/configdir_test.go
+++ b/hugolib/configdir_test.go
@@ -146,7 +146,7 @@ baseURL = "https://example.org"
_, _, err := LoadConfig(ConfigSourceDescriptor{Fs: mm, Environment: "development", Filename: "hugo.toml", AbsConfigDir: "config"})
c.Assert(err, qt.Not(qt.IsNil))
- fe := herrors.UnwrapErrorWithFileContext(err)
+ fe := herrors.UnwrapFileError(err)
c.Assert(fe, qt.Not(qt.IsNil))
c.Assert(fe.Position().Filename, qt.Equals, filepath.FromSlash("config/development/config.toml"))
}
diff --git a/hugolib/content_factory.go b/hugolib/content_factory.go
index bea98894d..e6e82979f 100644
--- a/hugolib/content_factory.go
+++ b/hugolib/content_factory.go
@@ -14,6 +14,7 @@
package hugolib
import (
+ "fmt"
"io"
"path/filepath"
"strings"
@@ -25,7 +26,6 @@ import (
"github.com/gohugoio/hugo/resources/page"
- "github.com/pkg/errors"
"github.com/spf13/afero"
)
@@ -48,12 +48,12 @@ func (f ContentFactory) ApplyArchetypeFilename(w io.Writer, p page.Page, archety
}
if fi.IsDir() {
- return errors.Errorf("archetype directory (%q) not supported", archetypeFilename)
+ return fmt.Errorf("archetype directory (%q) not supported", archetypeFilename)
}
templateSource, err := afero.ReadFile(f.h.SourceFilesystems.Archetypes.Fs, archetypeFilename)
if err != nil {
- return errors.Wrapf(err, "failed to read archetype file %q: %s", archetypeFilename, err)
+ return fmt.Errorf("failed to read archetype file %q: %s: %w", archetypeFilename, err, err)
}
@@ -79,12 +79,12 @@ func (f ContentFactory) ApplyArchetypeTemplate(w io.Writer, p page.Page, archety
templ, err := ps.s.TextTmpl().Parse("archetype.md", string(templateSource))
if err != nil {
- return errors.Wrapf(err, "failed to parse archetype template: %s", err)
+ return fmt.Errorf("failed to parse archetype template: %s: %w", err, err)
}
result, err := executeToString(ps.s.Tmpl(), templ, d)
if err != nil {
- return errors.Wrapf(err, "failed to execute archetype template: %s", err)
+ return fmt.Errorf("failed to execute archetype template: %s: %w", err, err)
}
_, err = io.WriteString(w, f.shortcodeReplacerPost.Replace(result))
diff --git a/hugolib/content_map.go b/hugolib/content_map.go
index 330391dcb..6849998b6 100644
--- a/hugolib/content_map.go
+++ b/hugolib/content_map.go
@@ -23,7 +23,6 @@ import (
"github.com/gohugoio/hugo/helpers"
"github.com/gohugoio/hugo/resources/page"
- "github.com/pkg/errors"
"github.com/gohugoio/hugo/hugofs/files"
@@ -207,7 +206,7 @@ func (b *cmInsertKeyBuilder) WithFile(fi hugofs.FileMetaInfo) *cmInsertKeyBuilde
p, k := b.getBundle(p)
if k == "" {
- b.err = errors.Errorf("no bundle header found for %q", bundlePath)
+ b.err = fmt.Errorf("no bundle header found for %q", bundlePath)
return b
}
diff --git a/hugolib/content_map_page.go b/hugolib/content_map_page.go
index 21a4e8f2a..a16e4720d 100644
--- a/hugolib/content_map_page.go
+++ b/hugolib/content_map_page.go
@@ -35,7 +35,6 @@ import (
"github.com/spf13/cast"
"github.com/gohugoio/hugo/common/para"
- "github.com/pkg/errors"
)
func newPageMaps(h *HugoSites) *pageMaps {
@@ -131,13 +130,13 @@ func (m *pageMap) newPageFromContentNode(n *contentNode, parentBucket *pagesMapB
gi, err := s.h.gitInfoForPage(ps)
if err != nil {
- return nil, errors.Wrap(err, "failed to load Git data")
+ return nil, fmt.Errorf("failed to load Git data: %w", err)
}
ps.gitInfo = gi
owners, err := s.h.codeownersForPage(ps)
if err != nil {
- return nil, errors.Wrap(err, "failed to load CODEOWNERS")
+ return nil, fmt.Errorf("failed to load CODEOWNERS: %w", err)
}
ps.codeowners = owners
@@ -282,7 +281,7 @@ func (m *pageMap) createSiteTaxonomies() error {
} else {
taxonomy := m.s.taxonomies[viewName.plural]
if taxonomy == nil {
- walkErr = errors.Errorf("missing taxonomy: %s", viewName.plural)
+ walkErr = fmt.Errorf("missing taxonomy: %s", viewName.plural)
return true
}
m.taxonomyEntries.WalkPrefix(s, func(ss string, v any) bool {
diff --git a/hugolib/fileInfo.go b/hugolib/fileInfo.go
index fdfd34b16..1cdd7041d 100644
--- a/hugolib/fileInfo.go
+++ b/hugolib/fileInfo.go
@@ -14,12 +14,11 @@
package hugolib
import (
+ "fmt"
"strings"
"github.com/gohugoio/hugo/hugofs/files"
- "github.com/pkg/errors"
-
"github.com/gohugoio/hugo/hugofs"
"github.com/spf13/afero"
@@ -41,7 +40,7 @@ type fileInfo struct {
func (fi *fileInfo) Open() (afero.File, error) {
f, err := fi.FileInfo().Meta().Open()
if err != nil {
- err = errors.Wrap(err, "fileInfo")
+ err = fmt.Errorf("fileInfo: %w", err)
}
return f, err
diff --git a/hugolib/filesystems/basefs.go b/hugolib/filesystems/basefs.go
index d02f8c624..2447246d6 100644
--- a/hugolib/filesystems/basefs.go
+++ b/hugolib/filesystems/basefs.go
@@ -35,8 +35,6 @@ import (
"github.com/gohugoio/hugo/hugofs/files"
- "github.com/pkg/errors"
-
"github.com/gohugoio/hugo/modules"
hpaths "github.com/gohugoio/hugo/common/paths"
@@ -176,7 +174,7 @@ func (b *BaseFs) AbsProjectContentDir(filename string) (string, string, error) {
}
- return "", "", errors.Errorf("could not determine content directory for %q", filename)
+ return "", "", fmt.Errorf("could not determine content directory for %q", filename)
}
// ResolveJSConfigFile resolves the JS-related config file to a absolute
@@ -468,7 +466,7 @@ func NewBase(p *paths.Paths, logger loggers.Logger, options ...func(*BaseFs) err
builder := newSourceFilesystemsBuilder(p, logger, b)
sourceFilesystems, err := builder.Build()
if err != nil {
- return nil, errors.Wrap(err, "build filesystems")
+ return nil, fmt.Errorf("build filesystems: %w", err)
}
b.SourceFilesystems = sourceFilesystems
@@ -502,7 +500,7 @@ func (b *sourceFilesystemsBuilder) Build() (*SourceFilesystems, error) {
if b.theBigFs == nil {
theBigFs, err := b.createMainOverlayFs(b.p)
if err != nil {
- return nil, errors.Wrap(err, "create main fs")
+ return nil, fmt.Errorf("create main fs: %w", err)
}
b.theBigFs = theBigFs
@@ -544,7 +542,7 @@ func (b *sourceFilesystemsBuilder) Build() (*SourceFilesystems, error) {
contentFs, err := hugofs.NewLanguageFs(b.p.LanguagesDefaultFirst.AsOrdinalSet(), contentBfs)
if err != nil {
- return nil, errors.Wrap(err, "create content filesystem")
+ return nil, fmt.Errorf("create content filesystem: %w", err)
}
b.result.Content = b.newSourceFilesystem(files.ComponentFolderContent, contentFs, contentDirs)
diff --git a/hugolib/hugo_sites.go b/hugolib/hugo_sites.go
index d67652dab..e0d69a8af 100644
--- a/hugolib/hugo_sites.go
+++ b/hugolib/hugo_sites.go
@@ -15,6 +15,7 @@ package hugolib
import (
"context"
+ "fmt"
"io"
"path/filepath"
"sort"
@@ -33,9 +34,10 @@ import (
"github.com/gohugoio/hugo/output"
"github.com/gohugoio/hugo/parser/metadecoders"
+ "errors"
+
"github.com/gohugoio/hugo/common/para"
"github.com/gohugoio/hugo/hugofs"
- "github.com/pkg/errors"
"github.com/gohugoio/hugo/source"
@@ -194,7 +196,7 @@ func (h *hugoSitesInit) Reset() {
func (h *HugoSites) Data() map[string]any {
if _, err := h.init.data.Do(); err != nil {
- h.SendError(errors.Wrap(err, "failed to load data"))
+ h.SendError(fmt.Errorf("failed to load data: %w", err))
return nil
}
return h.data
@@ -242,7 +244,7 @@ func (h *HugoSites) pickOneAndLogTheRest(errors []error) error {
for j, err := range errors {
// If this is in server mode, we want to return an error to the client
// with a file context, if possible.
- if herrors.UnwrapErrorWithFileContext(err) != nil {
+ if herrors.UnwrapFileError(err) != nil {
i = j
break
}
@@ -327,7 +329,7 @@ func newHugoSites(cfg deps.DepsCfg, sites ...*Site) (*HugoSites, error) {
langConfig, err := newMultiLingualFromSites(cfg.Cfg, sites...)
if err != nil {
- return nil, errors.Wrap(err, "failed to create language config")
+ return nil, fmt.Errorf("failed to create language config: %w", err)
}
var contentChangeTracker *contentChangeMap
@@ -365,7 +367,7 @@ func newHugoSites(cfg deps.DepsCfg, sites ...*Site) (*HugoSites, error) {
h.init.data.Add(func() (any, error) {
err := h.loadData(h.PathSpec.BaseFs.Data.Dirs)
if err != nil {
- return nil, errors.Wrap(err, "failed to load data")
+ return nil, fmt.Errorf("failed to load data: %w", err)
}
return nil, nil
})
@@ -391,7 +393,7 @@ func newHugoSites(cfg deps.DepsCfg, sites ...*Site) (*HugoSites, error) {
h.init.gitInfo.Add(func() (any, error) {
err := h.loadGitInfo()
if err != nil {
- return nil, errors.Wrap(err, "failed to load Git info")
+ return nil, fmt.Errorf("failed to load Git info: %w", err)
}
return nil, nil
})
@@ -402,7 +404,7 @@ func newHugoSites(cfg deps.DepsCfg, sites ...*Site) (*HugoSites, error) {
var l configLoader
if err := l.applyDeps(cfg, sites...); err != nil {
- initErr = errors.Wrap(err, "add site dependencies")
+ initErr = fmt.Errorf("add site dependencies: %w", err)
}
h.Deps = sites[0].Deps
@@ -485,7 +487,7 @@ func (l configLoader) applyDeps(cfg deps.DepsCfg, sites ...*Site) error {
siteConfig, err := l.loadSiteConfig(s.language)
if err != nil {
- return errors.Wrap(err, "load site config")
+ return fmt.Errorf("load site config: %w", err)
}
s.siteConfigConfig = siteConfig
@@ -516,17 +518,17 @@ func (l configLoader) applyDeps(cfg deps.DepsCfg, sites ...*Site) error {
var err error
d, err = deps.New(cfg)
if err != nil {
- return errors.Wrap(err, "create deps")
+ return fmt.Errorf("create deps: %w", err)
}
d.OutputFormatsConfig = s.outputFormatsConfig
if err := onCreated(d); err != nil {
- return errors.Wrap(err, "on created")
+ return fmt.Errorf("on created: %w", err)
}
if err = d.LoadResources(); err != nil {
- return errors.Wrap(err, "load resources")
+ return fmt.Errorf("load resources: %w", err)
}
} else {
@@ -548,7 +550,7 @@ func NewHugoSites(cfg deps.DepsCfg) (*HugoSites, error) {
}
sites, err := createSitesFromConfig(cfg)
if err != nil {
- return nil, errors.Wrap(err, "from config")
+ return nil, fmt.Errorf("from config: %w", err)
}
return newHugoSites(cfg, sites...)
}
@@ -882,7 +884,7 @@ func (h *HugoSites) handleDataFile(r source.File) error {
f, err := r.FileInfo().Meta().Open()
if err != nil {
- return errors.Wrapf(err, "data: failed to open %q:", r.LogicalName())
+ return fmt.Errorf("data: failed to open %q: %w", r.LogicalName(), err)
}
defer f.Close()
@@ -960,23 +962,16 @@ func (h *HugoSites) errWithFileContext(err error, f source.File) error {
if !ok {
return err
}
-
realFilename := fim.Meta().Filename
- err, _ = herrors.WithFileContextForFile(
- err,
- realFilename,
- realFilename,
- h.SourceSpec.Fs.Source,
- herrors.SimpleLineMatcher)
+ return herrors.NewFileErrorFromFile(err, realFilename, realFilename, h.SourceSpec.Fs.Source, herrors.SimpleLineMatcher)
- return err
}
func (h *HugoSites) readData(f source.File) (any, error) {
file, err := f.FileInfo().Meta().Open()
if err != nil {
- return nil, errors.Wrap(err, "readData: failed to open data file")
+ return nil, fmt.Errorf("readData: failed to open data file: %w", err)
}
defer file.Close()
content := helpers.ReaderToBytes(file)
diff --git a/hugolib/hugo_sites_build.go b/hugolib/hugo_sites_build.go
index 4616b6dbb..1a191257c 100644
--- a/hugolib/hugo_sites_build.go
+++ b/hugolib/hugo_sites_build.go
@@ -35,7 +35,7 @@ import (
"github.com/gohugoio/hugo/output"
- "github.com/pkg/errors"
+ "errors"
"github.com/fsnotify/fsnotify"
"github.com/gohugoio/hugo/helpers"
@@ -50,7 +50,7 @@ func (h *HugoSites) Build(config BuildCfg, events ...fsnotify.Event) error {
if !config.NoBuildLock {
unlock, err := h.BaseFs.LockBuild()
if err != nil {
- return errors.Wrap(err, "failed to acquire a build lock")
+ return fmt.Errorf("failed to acquire a build lock: %w", err)
}
defer unlock()
}
@@ -99,11 +99,11 @@ func (h *HugoSites) Build(config BuildCfg, events ...fsnotify.Event) error {
if len(events) > 0 {
// Rebuild
if err := h.initRebuild(conf); err != nil {
- return errors.Wrap(err, "initRebuild")
+ return fmt.Errorf("initRebuild: %w", err)
}
} else {
if err := h.initSites(conf); err != nil {
- return errors.Wrap(err, "initSites")
+ return fmt.Errorf("initSites: %w", err)
}
}
@@ -117,7 +117,7 @@ func (h *HugoSites) Build(config BuildCfg, events ...fsnotify.Event) error {
}
trace.WithRegion(ctx, "process", f)
if err != nil {
- return errors.Wrap(err, "process")
+ return fmt.Errorf("process: %w", err)
}
f = func() {
diff --git a/hugolib/hugo_sites_build_errors_test.go b/hugolib/hugo_sites_build_errors_test.go
index 8b23e7ac7..8f983075d 100644
--- a/hugolib/hugo_sites_build_errors_test.go
+++ b/hugolib/hugo_sites_build_errors_test.go
@@ -2,6 +2,7 @@ package hugolib
import (
"fmt"
+ "os"
"path/filepath"
"strings"
"testing"
@@ -17,14 +18,15 @@ type testSiteBuildErrorAsserter struct {
c *qt.C
}
-func (t testSiteBuildErrorAsserter) getFileError(err error) *herrors.ErrorWithFileContext {
+func (t testSiteBuildErrorAsserter) getFileError(err error) herrors.FileError {
t.c.Assert(err, qt.Not(qt.IsNil), qt.Commentf(t.name))
- ferr := herrors.UnwrapErrorWithFileContext(err)
- t.c.Assert(ferr, qt.Not(qt.IsNil))
- return ferr
+ fe := herrors.UnwrapFileError(err)
+ t.c.Assert(fe, qt.Not(qt.IsNil))
+ return fe
}
func (t testSiteBuildErrorAsserter) assertLineNumber(lineNumber int, err error) {
+ t.c.Helper()
fe := t.getFileError(err)
t.c.Assert(fe.Position().LineNumber, qt.Equals, lineNumber, qt.Commentf(err.Error()))
}
@@ -87,7 +89,6 @@ func TestSiteBuildErrors(t *testing.T) {
fe := a.getFileError(err)
a.c.Assert(fe.Position().LineNumber, qt.Equals, 5)
a.c.Assert(fe.Position().ColumnNumber, qt.Equals, 1)
- a.c.Assert(fe.ChromaLexer, qt.Equals, "go-html-template")
a.assertErrorMessage("\"layouts/foo/single.html:5:1\": parse failed: template: foo/single.html:5: unexpected \"}\" in operand", fe.Error())
},
},
@@ -101,7 +102,6 @@ func TestSiteBuildErrors(t *testing.T) {
fe := a.getFileError(err)
a.c.Assert(fe.Position().LineNumber, qt.Equals, 5)
a.c.Assert(fe.Position().ColumnNumber, qt.Equals, 14)
- a.c.Assert(fe.ChromaLexer, qt.Equals, "go-html-template")
a.assertErrorMessage("\"layouts/_default/single.html:5:14\": execute of template failed", fe.Error())
},
},
@@ -115,7 +115,6 @@ func TestSiteBuildErrors(t *testing.T) {
fe := a.getFileError(err)
a.c.Assert(fe.Position().LineNumber, qt.Equals, 5)
a.c.Assert(fe.Position().ColumnNumber, qt.Equals, 14)
- a.c.Assert(fe.ChromaLexer, qt.Equals, "go-html-template")
a.assertErrorMessage("\"layouts/_default/single.html:5:14\": execute of template failed", fe.Error())
},
},
@@ -130,18 +129,17 @@ func TestSiteBuildErrors(t *testing.T) {
},
},
{
- name: "Shortode execute failed",
+ name: "Shortcode execute failed",
fileType: shortcode,
fileFixer: func(content string) string {
return strings.Replace(content, ".Title", ".Titles", 1)
},
assertBuildError: func(a testSiteBuildErrorAsserter, err error) {
fe := a.getFileError(err)
- a.c.Assert(fe.Position().LineNumber, qt.Equals, 7)
- a.c.Assert(fe.ChromaLexer, qt.Equals, "md")
// Make sure that it contains both the content file and template
- a.assertErrorMessage(`content/myyaml.md:7:10": failed to render shortcode "sc"`, fe.Error())
- a.assertErrorMessage(`shortcodes/sc.html:4:22: executing "shortcodes/sc.html" at <.Page.Titles>: can't evaluate`, fe.Error())
+ a.assertErrorMessage(`"content/myyaml.md:7:10": failed to render shortcode "sc": failed to process shortcode: "layouts/shortcodes/sc.html:4:22": execute of template failed: template: shortcodes/sc.html:4:22: executing "shortcodes/sc.html" at <.Page.Titles>: can't evaluate field Titles in type page.Page`, fe.Error())
+ a.c.Assert(fe.Position().LineNumber, qt.Equals, 7)
+
},
},
{
@@ -154,7 +152,6 @@ func TestSiteBuildErrors(t *testing.T) {
fe := a.getFileError(err)
a.c.Assert(fe.Position().LineNumber, qt.Equals, 7)
a.c.Assert(fe.Position().ColumnNumber, qt.Equals, 10)
- a.c.Assert(fe.ChromaLexer, qt.Equals, "md")
a.assertErrorMessage(`"content/myyaml.md:7:10": failed to extract shortcode: template for shortcode "nono" not found`, fe.Error())
},
},
@@ -162,10 +159,14 @@ func TestSiteBuildErrors(t *testing.T) {
name: "Invalid YAML front matter",
fileType: yamlcontent,
fileFixer: func(content string) string {
- return strings.Replace(content, "title:", "title: %foo", 1)
+ return `---
+title: "My YAML Content"
+foo bar
+---
+`
},
assertBuildError: func(a testSiteBuildErrorAsserter, err error) {
- a.assertLineNumber(2, err)
+ a.assertLineNumber(3, err)
},
},
{
@@ -177,7 +178,6 @@ func TestSiteBuildErrors(t *testing.T) {
assertBuildError: func(a testSiteBuildErrorAsserter, err error) {
fe := a.getFileError(err)
a.c.Assert(fe.Position().LineNumber, qt.Equals, 6)
- a.c.Assert(fe.ErrorContext.ChromaLexer, qt.Equals, "toml")
},
},
{
@@ -188,9 +188,7 @@ func TestSiteBuildErrors(t *testing.T) {
},
assertBuildError: func(a testSiteBuildErrorAsserter, err error) {
fe := a.getFileError(err)
-
a.c.Assert(fe.Position().LineNumber, qt.Equals, 3)
- a.c.Assert(fe.ErrorContext.ChromaLexer, qt.Equals, "json")
},
},
{
@@ -211,6 +209,9 @@ func TestSiteBuildErrors(t *testing.T) {
}
for _, test := range tests {
+ if test.name != "Invalid JSON front matter" {
+ continue
+ }
test := test
t.Run(test.name, func(t *testing.T) {
t.Parallel()
@@ -311,6 +312,77 @@ Some content.
}
})
}
+
+}
+
+// Issue 9852
+func TestErrorMinify(t *testing.T) {
+ t.Parallel()
+
+ files := `
+-- config.toml --
+minify = true
+
+-- layouts/index.html --
+<body>
+<script>=;</script>
+</body>
+
+`
+
+ b, err := NewIntegrationTestBuilder(
+ IntegrationTestConfig{
+ T: t,
+ TxtarString: files,
+ },
+ ).BuildE()
+
+ fe := herrors.UnwrapFileError(err)
+ b.Assert(fe, qt.IsNotNil)
+ b.Assert(fe.Position().LineNumber, qt.Equals, 2)
+ b.Assert(fe.Position().ColumnNumber, qt.Equals, 9)
+ b.Assert(fe.Error(), qt.Contains, "unexpected = in expression on line 2 and column 9")
+ b.Assert(filepath.ToSlash(fe.Position().Filename), qt.Contains, "hugo-transform-error")
+ b.Assert(os.Remove(fe.Position().Filename), qt.IsNil)
+
+}
+
+func TestErrorNested(t *testing.T) {
+ t.Parallel()
+
+ files := `
+-- config.toml --
+-- layouts/index.html --
+line 1
+12{{ partial "foo.html" . }}
+line 4
+line 5
+-- layouts/partials/foo.html --
+line 1
+line 2
+123{{ .ThisDoesNotExist }}
+line 4
+`
+
+ b, err := NewIntegrationTestBuilder(
+ IntegrationTestConfig{
+ T: t,
+ TxtarString: files,
+ },
+ ).BuildE()
+
+ b.Assert(err, qt.IsNotNil)
+ errors := herrors.UnwrapFileErrorsWithErrorContext(err)
+ b.Assert(errors, qt.HasLen, 2)
+ fmt.Println(errors[0])
+ b.Assert(errors[0].Position().LineNumber, qt.Equals, 2)
+ b.Assert(errors[0].Position().ColumnNumber, qt.Equals, 5)
+ b.Assert(errors[0].Error(), qt.Contains, filepath.FromSlash(`"/layouts/index.html:2:5": execute of template failed`))
+ b.Assert(errors[0].ErrorContext().Lines, qt.DeepEquals, []string{"line 1", "12{{ partial \"foo.html\" . }}", "line 4", "line 5"})
+ b.Assert(errors[1].Position().LineNumber, qt.Equals, 3)
+ b.Assert(errors[1].Position().ColumnNumber, qt.Equals, 6)
+ b.Assert(errors[1].ErrorContext().Lines, qt.DeepEquals, []string{"line 1", "line 2", "123{{ .ThisDoesNotExist }}", "line 4"})
+
}
// https://github.com/gohugoio/hugo/issues/5375
diff --git a/hugolib/integrationtest_builder.go b/hugolib/integrationtest_builder.go
index 58e751892..c3fb9fffc 100644
--- a/hugolib/integrationtest_builder.go
+++ b/hugolib/integrationtest_builder.go
@@ -169,8 +169,7 @@ func (s *IntegrationTestBuilder) destinationExists(filename string) bool {
}
func (s *IntegrationTestBuilder) AssertIsFileError(err error) {
- var ferr *herrors.ErrorWithFileContext
- s.Assert(err, qt.ErrorAs, &ferr)
+ s.Assert(err, qt.ErrorAs, new(herrors.FileError))
}
func (s *IntegrationTestBuilder) AssertRenderCountContent(count int) {
diff --git a/hugolib/page.go b/hugolib/page.go
index 77165c072..4faefa3cc 100644
--- a/hugolib/page.go
+++ b/hugolib/page.go
@@ -39,8 +39,9 @@ import (
"github.com/gohugoio/hugo/common/herrors"
"github.com/gohugoio/hugo/parser/metadecoders"
+ "errors"
+
"github.com/gohugoio/hugo/parser/pageparser"
- "github.com/pkg/errors"
"github.com/gohugoio/hugo/output"
@@ -482,7 +483,7 @@ func (p *pageState) renderResources() (err error) {
src, ok := r.(resource.Source)
if !ok {
- err = errors.Errorf("Resource %T does not support resource.Source", src)
+ err = fmt.Errorf("Resource %T does not support resource.Source", src)
return
}
@@ -560,23 +561,37 @@ func (p *pageState) addDependency(dep identity.Provider) {
// wrapError adds some more context to the given error if possible/needed
func (p *pageState) wrapError(err error) error {
- if _, ok := err.(*herrors.ErrorWithFileContext); ok {
- // Preserve the first file context.
- return err
+ if err == nil {
+ panic("wrapError with nil")
}
- var filename string