build: return ErrorList type

Adds a very similar interface to go/scanner package for returning a list
of errors.

Updates #34
This commit is contained in:
Michael McLoughlin
2019-01-06 13:32:09 -08:00
parent b6576feee6
commit 07901bb91b
4 changed files with 80 additions and 19 deletions

View File

@@ -1,6 +1,9 @@
package build
import (
"fmt"
"log"
"github.com/mmcloughlin/avo/internal/stack"
"github.com/mmcloughlin/avo/src"
)
@@ -28,3 +31,53 @@ func (e Error) Error() string {
}
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)
}
// 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 {
l.Printf("%s\n", e)
if max > 0 && i == max {
l.Print("too many errors")
return
}
}
} else if err != nil {
l.Printf("%s\n", err)
}
}