Skip to content

Commit

Permalink
build: include position information in errors
Browse files Browse the repository at this point in the history
  • Loading branch information
mmcloughlin committed Jan 4, 2019
1 parent 80c427d commit 05cfa80
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 2 deletions.
3 changes: 2 additions & 1 deletion build/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,8 @@ func (c *Context) activeglobal() *avo.Global {
}

func (c *Context) AddError(err error) {
c.errs = append(c.errs, err)
e := exterr(err)
c.errs = append(c.errs, e)
}

func (c *Context) AddErrorMessage(msg string) {
Expand Down
30 changes: 30 additions & 0 deletions build/error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package build

import (
"github.com/mmcloughlin/avo/internal/stack"
"github.com/mmcloughlin/avo/src"
)

// Error represents an error during building, optionally tagged with the position at which it happened.
type Error struct {
Position src.Position
Err error
}

// exterr constructs an Error with position derived from the first frame in the
// call stack outside this package.
func exterr(err error) Error {
e := Error{Err: err}
if f := stack.ExternalCaller(); f != nil {
e.Position = src.FramePosition(*f).Relwd()
}
return e
}

func (e Error) Error() string {
msg := e.Err.Error()
if e.Position.IsValid() {
return e.Position.String() + ": " + msg
}
return msg
}
34 changes: 33 additions & 1 deletion src/src.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
package src

import "strconv"
import (
"os"
"path/filepath"
"runtime"
"strconv"
)

// Position represents a position in a source file.
type Position struct {
Filename string
Line int // 1-up
}

func FramePosition(f runtime.Frame) Position {
return Position{
Filename: f.File,
Line: f.Line,
}
}

// IsValid reports whether the position is valid: Line must be positive, but
// Filename may be empty.
func (p Position) IsValid() bool {
Expand All @@ -26,3 +38,23 @@ func (p Position) String() string {
s += strconv.Itoa(p.Line)
return s
}

// Rel returns Position relative to basepath. If the given filename cannot be
// expressed relative to basepath the position will be returned unchanged.
func (p Position) Rel(basepath string) Position {
q := p
if rel, err := filepath.Rel(basepath, q.Filename); err == nil {
q.Filename = rel
}
return q
}

// Relwd returns Position relative to the current working directory. Returns p
// unchanged if the working directory cannot be determined, or the filename
// cannot be expressed relative to the working directory.
func (p Position) Relwd() Position {
if wd, err := os.Getwd(); err == nil {
return p.Rel(wd)
}
return p
}

0 comments on commit 05cfa80

Please sign in to comment.