cue: add internal error types
Issue #52
Change-Id: I15a132abf391fd891672ae41f2213cd380d7d8f3
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/2203
Reviewed-by: Marcel van Lohuizen <mpvl@google.com>
diff --git a/cue/errors.go b/cue/errors.go
index c74708f..bc1e2ae 100644
--- a/cue/errors.go
+++ b/cue/errors.go
@@ -15,13 +15,66 @@
package cue
import (
+ "fmt"
"sort"
+ "cuelang.org/go/cue/ast"
+ "cuelang.org/go/cue/errors"
"cuelang.org/go/cue/token"
- "golang.org/x/exp/errors"
- "golang.org/x/exp/errors/fmt"
+ "golang.org/x/xerrors"
)
+// A nodeError is an error associated with processing an AST node.
+type nodeError struct {
+ path []string // optional
+ n ast.Node
+
+ errors.Message
+}
+
+func nodeErrorf(n ast.Node, format string, args ...interface{}) *nodeError {
+ return &nodeError{
+ n: n,
+ Message: errors.Message{Format: format, Args: args},
+ }
+}
+
+func (e *nodeError) Position() token.Position {
+ return e.n.Pos().Position()
+}
+
+func (e *nodeError) Path() []string {
+ return e.path
+}
+
+func (v Value) toErr(b *bottom) errors.Error {
+ return &valueError{
+ Message: errors.Message{
+ Format: b.msg,
+ Args: nil,
+ },
+ v: v,
+ err: b,
+ }
+}
+
+// A valueError is returned as a result of evaluating a value.
+type valueError struct {
+ errors.Message
+
+ v Value
+ err *bottom
+}
+
+func (e *valueError) Position() token.Position {
+ return e.err.pos.Pos().Position()
+}
+
+func (e *valueError) Path() (a []string) {
+ a, _ = e.v.path.appendPath(a, e.v.idx)
+ return a
+}
+
type errCode int
const (
@@ -109,7 +162,11 @@
func (x *bottom) Error() string { return fmt.Sprint(x) }
-func (x *bottom) FormatError(p errors.Printer) error {
+func (x *bottom) Format(s fmt.State, verb rune) {
+ xerrors.FormatError(x, s, verb)
+}
+
+func (x *bottom) FormatError(p xerrors.Printer) error {
p.Print(x.msg)
if p.Detail() && x.index != nil {
locs := appendLocations(nil, x.pos)
diff --git a/cue/value.go b/cue/value.go
index 66ae5e4..4ffbbb1 100644
--- a/cue/value.go
+++ b/cue/value.go
@@ -1245,6 +1245,7 @@
// Take the first error as an example.
err := x.values[0].val
if !isBottom(err) {
+ // TODO: use format instead of debugStr.
err = ctx.mkErr(src, debugStr(ctx, err))
}
return mVal{ctx.mkErr(src, "empty disjunction: %v", err), false}