diff options
Diffstat (limited to 'common/herrors')
-rw-r--r-- | common/herrors/file_error.go | 48 | ||||
-rw-r--r-- | common/herrors/file_error_test.go | 4 |
2 files changed, 42 insertions, 10 deletions
diff --git a/common/herrors/file_error.go b/common/herrors/file_error.go index 318245654..85007a057 100644 --- a/common/herrors/file_error.go +++ b/common/herrors/file_error.go @@ -142,7 +142,7 @@ func (e *fileError) Unwrap() error { // NewFileError creates a new FileError that wraps err. // The value for name should identify the file, the best // being the full filename to the file on disk. -func NewFileError(name string, err error) FileError { +func NewFileError(err error, name string) FileError { // Filetype is used to determine the Chroma lexer to use. fileType, pos := extractFileTypePos(err) pos.Filename = name @@ -155,7 +155,7 @@ func NewFileError(name string, err error) FileError { } // NewFileErrorFromPos will use the filename and line number from pos to create a new FileError, wrapping err. -func NewFileErrorFromPos(pos text.Position, err error) FileError { +func NewFileErrorFromPos(err error, pos text.Position) FileError { // Filetype is used to determine the Chroma lexer to use. fileType, _ := extractFileTypePos(err) if fileType == "" { @@ -165,20 +165,52 @@ func NewFileErrorFromPos(pos text.Position, err error) FileError { } +func NewFileErrorFromFileInPos(err error, pos text.Position, fs afero.Fs, linematcher LineMatcherFn) FileError { + if err == nil { + panic("err is nil") + } + f, realFilename, err2 := openFile(pos.Filename, fs) + if err2 != nil { + return NewFileErrorFromPos(err, pos) + } + pos.Filename = realFilename + defer f.Close() + return NewFileErrorFromPos(err, pos).UpdateContent(f, linematcher) +} + // NewFileErrorFromFile is a convenience method to create a new FileError from a file. -func NewFileErrorFromFile(err error, filename, realFilename string, fs afero.Fs, linematcher LineMatcherFn) FileError { +func NewFileErrorFromFile(err error, filename string, fs afero.Fs, linematcher LineMatcherFn) FileError { if err == nil { panic("err is nil") } - if linematcher == nil { - linematcher = SimpleLineMatcher + f, realFilename, err2 := openFile(filename, fs) + if err2 != nil { + return NewFileError(err, realFilename) } + defer f.Close() + return NewFileError(err, realFilename).UpdateContent(f, linematcher) +} + +func openFile(filename string, fs afero.Fs) (afero.File, string, error) { + realFilename := filename + + // We want the most specific filename possible in the error message. + fi, err2 := fs.Stat(filename) + if err2 == nil { + if s, ok := fi.(interface { + Filename() string + }); ok { + realFilename = s.Filename() + } + + } + f, err2 := fs.Open(filename) if err2 != nil { - return NewFileError(realFilename, err) + return nil, realFilename, err2 } - defer f.Close() - return NewFileError(realFilename, err).UpdateContent(f, linematcher) + + return f, realFilename, nil } // Cause returns the underlying error or itself if it does not implement Unwrap. diff --git a/common/herrors/file_error_test.go b/common/herrors/file_error_test.go index 41e244109..04baadf16 100644 --- a/common/herrors/file_error_test.go +++ b/common/herrors/file_error_test.go @@ -30,7 +30,7 @@ func TestNewFileError(t *testing.T) { c := qt.New(t) - fe := NewFileError("foo.html", errors.New("bar")) + fe := NewFileError(errors.New("bar"), "foo.html") c.Assert(fe.Error(), qt.Equals, `"foo.html:1:1": bar`) lines := "" @@ -70,7 +70,7 @@ func TestNewFileErrorExtractFromMessage(t *testing.T) { {errors.New(`execute of template failed: template: index.html:2:5: executing "index.html" at <partial "foo.html" .>: error calling partial: "/layouts/partials/foo.html:3:6": execute of template failed: template: partials/foo.html:3:6: executing "partials/foo.html" at <.ThisDoesNotExist>: can't evaluate field ThisDoesNotExist in type *hugolib.pageStat`), 0, 2, 5}, } { - got := NewFileError("test.txt", test.in) + got := NewFileError(test.in, "test.txt") errMsg := qt.Commentf("[%d][%T]", i, got) |