cue/errors: print positions explicitly
This gives more control over printing and
prepares for error rework.
Issue #52
Change-Id: I5629109298341cc700f860a6610f9362b7741a22
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/2168
Reviewed-by: Marcel van Lohuizen <mpvl@google.com>
diff --git a/cmd/cue/cmd/testdata/tasks/cmd_baddisplay.out b/cmd/cue/cmd/testdata/tasks/cmd_baddisplay.out
index c691b70..753329f 100644
--- a/cmd/cue/cmd/testdata/tasks/cmd_baddisplay.out
+++ b/cmd/cue/cmd/testdata/tasks/cmd_baddisplay.out
@@ -1,4 +1,3 @@
unsupported op &(int, string):
$CWD/testdata/tasks/task_tool.cue:29:9
tool/cli:4:9
-
diff --git a/cue/errors.go b/cue/errors.go
index 62aa4e7..5ffa449 100644
--- a/cue/errors.go
+++ b/cue/errors.go
@@ -81,7 +81,7 @@
func (x *bottom) kind() kind { return bottomKind }
-func (x *bottom) Position() []token.Pos {
+func (x *bottom) Positions() []token.Pos {
if x.index != nil {
return appendPositions(nil, x.pos)
}
diff --git a/cue/errors/errors.go b/cue/errors/errors.go
index 61e4dab..949da11 100644
--- a/cue/errors/errors.go
+++ b/cue/errors/errors.go
@@ -22,6 +22,7 @@
"cuelang.org/go/cue/token"
"golang.org/x/exp/errors"
"golang.org/x/exp/errors/fmt"
+ "golang.org/x/xerrors"
)
// New is a convenience wrapper for errors.New in the core library.
@@ -115,14 +116,14 @@
return &posError{err: err}
}
-func (e posError) Position() token.Position {
+func (e *posError) Position() token.Position {
return e.pos
}
// Error implements the error interface.
-func (e posError) Error() string { return fmt.Sprint(e) }
+func (e *posError) Error() string { return fmt.Sprint(e) }
-func (e posError) FormatError(p errors.Printer) error {
+func (e *posError) FormatError(p errors.Printer) error {
next := e.err
if e.msg == "" {
next = errFormat(p, e.err)
@@ -136,6 +137,10 @@
}
+func (e posError) Unwrap() error {
+ return e.err
+}
+
func errFormat(p errors.Printer, err error) (next error) {
switch v := err.(type) {
case errors.Formatter:
@@ -250,6 +255,30 @@
}
}
-func printError(w io.Writer, err Error) {
- fmt.Fprintf(w, "%+v\n", err)
+func printError(w io.Writer, err error) {
+ fmt.Fprintf(w, "%v", err)
+ printedColon := false
+ for ; err != nil; err = xerrors.Unwrap(err) {
+ switch x := err.(type) {
+ case interface{ Position() token.Position }:
+ if pos := x.Position().String(); pos != "-" {
+ if !printedColon {
+ fmt.Fprint(w, ":")
+ printedColon = true
+ }
+ fmt.Fprintf(w, "\n %v", pos)
+ }
+ case interface{ Positions() []token.Pos }:
+ for _, p := range x.Positions() {
+ if p.IsValid() {
+ if !printedColon {
+ fmt.Fprint(w, ":")
+ printedColon = true
+ }
+ fmt.Fprintf(w, "\n %v", p)
+ }
+ }
+ }
+ }
+ fmt.Fprintln(w)
}