diff --git a/pipelines/pipeline.go b/pipelines/pipeline.go index 58a0577..4e69030 100644 --- a/pipelines/pipeline.go +++ b/pipelines/pipeline.go @@ -82,12 +82,12 @@ func (p *Pipeline) Render(w io.Writer, b []byte, filename string, lineNo int, e func (p *Pipeline) renderTemplate(src []byte, b map[string]interface{}, filename string, lineNo int) ([]byte, error) { tpl, err := p.liquidEngine.ParseTemplate(src) if err != nil { - return nil, utils.WrapPathError(err, "Liquid Error", filename) + return nil, utils.WrapPathError(err, filename) } tpl.SetSourceLocation(filename, lineNo) out, err := tpl.Render(b) if err != nil { - return nil, utils.WrapPathError(err, "Liquid Error", filename) + return nil, utils.WrapPathError(err, filename) } return out, err } @@ -106,7 +106,7 @@ func (p *Pipeline) ApplyLayout(name string, data []byte, e map[string]interface{ }) data, err = tpl.Render(b) if err != nil { - return nil, utils.WrapPathError(err, "render template", name) + return nil, utils.WrapPathError(err, name) } name = templates.VariableMap(lfm).String("layout", "") } diff --git a/site/data.go b/site/data.go index 9e120ec..15b565f 100644 --- a/site/data.go +++ b/site/data.go @@ -35,7 +35,7 @@ func (s *Site) readDataFiles() error { var d interface{} // map or slice err = utils.UnmarshalYAMLInterface(b, &d) if err != nil { - return utils.WrapPathError(err, "read YAML", filename) + return utils.WrapPathError(err, filename) } basename := utils.TrimExt(filepath.Base(f.Name())) s.data[basename] = d diff --git a/site/read.go b/site/read.go index d4e25d5..bb8ae85 100644 --- a/site/read.go +++ b/site/read.go @@ -74,7 +74,7 @@ func (s *Site) readFiles() error { defaultFrontmatter := s.config.GetFrontMatterDefaults("", relname) p, err := pages.NewFile(s, filename, filepath.ToSlash(relname), defaultFrontmatter) if err != nil { - return utils.WrapPathError(err, "read", filename) + return utils.WrapPathError(err, filename) } s.AddDocument(p, true) return nil diff --git a/utils/errors.go b/utils/errors.go new file mode 100644 index 0000000..7cee2cc --- /dev/null +++ b/utils/errors.go @@ -0,0 +1,40 @@ +package utils + +import ( + "fmt" + "os" +) + +// A PathError is an error with a source path. +// +// An os.PathError is unfortunately not a PathError, but this is still +// useful for deciding whether to wrap other errors. +type PathError interface { + error + Path() string +} + +type pathError struct { + cause error + path string +} + +func (p *pathError) Error() string { + return fmt.Sprintf("%s: %s", p.path, p.cause) +} + +// WrapPathError returns an error that will print with a path.\ +// It wraps its argument if it is not nil and does not already provide a path. +func WrapPathError(err error, path string) error { + if err == nil { + return nil + } + switch err := err.(type) { + case PathError: + return err + case *os.PathError: + return err + default: + return &pathError{path: path, cause: err} + } +} diff --git a/utils/ioutil.go b/utils/ioutil.go index 75d6ff8..cc599f2 100644 --- a/utils/ioutil.go +++ b/utils/ioutil.go @@ -81,21 +81,6 @@ func NewPathError(op, name, text string) *os.PathError { return &os.PathError{Op: op, Path: name, Err: errors.New(text)} } -// WrapPathError returns an instance of *os.WrapPathError, by wrapping its argument -// if it is not already an instance. -// WrapPathError returns nil for a nil argument. -func WrapPathError(err error, op, name string) *os.PathError { - if err == nil { - return nil - } - switch err := err.(type) { - case *os.PathError: - return err - default: - return &os.PathError{Op: op, Path: name, Err: err} - } -} - // RemoveEmptyDirectories recursively removes empty directories. func RemoveEmptyDirectories(root string) error { walkFn := func(name string, info os.FileInfo, err error) error {