vendor.github.com.mmcloughlin.avo.build.error.go Maven / Gradle / Ivy
package build
import (
"fmt"
"log"
"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
}
// ErrorList is a collection of errors for a source file.
type ErrorList []Error
// Add appends an error to the list.
func (e *ErrorList) Add(err Error) {
*e = append(*e, err)
}
// AddAt appends an error at position p.
func (e *ErrorList) AddAt(p src.Position, err error) {
e.Add(Error{p, err})
}
// addext appends an error to the list, tagged with the
func (e *ErrorList) addext(err error) {
e.Add(exterr(err))
}
// Err returns an error equivalent to this error list.
// If the list is empty, Err returns nil.
func (e ErrorList) Err() error {
if len(e) == 0 {
return nil
}
return e
}
// An ErrorList implements the error interface.
func (e ErrorList) Error() string {
switch len(e) {
case 0:
return "no errors"
case 1:
return e[0].Error()
}
return fmt.Sprintf("%s (and %d more errors)", e[0], len(e)-1)
}
// LogError logs a list of errors, one error per line, if the err parameter is
// an ErrorList. Otherwise it just logs the err string. Reports at most max
// errors, or unlimited if max is 0.
func LogError(l *log.Logger, err error, max int) {
if list, ok := err.(ErrorList); ok {
for i, e := range list {
if max > 0 && i == max {
l.Print("too many errors")
return
}
l.Printf("%s\n", e)
}
} else if err != nil {
l.Printf("%s\n", err)
}
}