cuelang.org/go@v0.13.0/cue/errors.go (about) 1 // Copyright 2018 The CUE Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package cue 16 17 import ( 18 "cuelang.org/go/cue/errors" 19 "cuelang.org/go/cue/token" 20 "cuelang.org/go/internal/core/adt" 21 ) 22 23 func (v Value) toErr(b *adt.Bottom) (err errors.Error) { 24 errs := errors.Errors(b.Err) 25 if len(errs) > 1 { 26 for _, e := range errs { 27 bb := *b 28 bb.Err = e 29 err = errors.Append(err, &valueError{v: v, err: &bb}) 30 } 31 return err 32 } 33 return &valueError{v: v, err: b} 34 } 35 36 var _ errors.Error = &valueError{} 37 38 // A valueError is returned as a result of evaluating a value. 39 type valueError struct { 40 v Value 41 err *adt.Bottom 42 } 43 44 func (e *valueError) Unwrap() error { 45 if e.err.Err == nil { 46 return nil 47 } 48 return errors.Unwrap(e.err.Err) 49 } 50 51 func (e *valueError) Bottom() *adt.Bottom { return e.err } 52 53 func (e *valueError) Error() string { 54 return errors.String(e) 55 } 56 57 func (e *valueError) Position() token.Pos { 58 if e.err.Err != nil { 59 return e.err.Err.Position() 60 } 61 src := e.err.Source() 62 if src == nil { 63 return token.NoPos 64 } 65 return src.Pos() 66 } 67 68 func (e *valueError) InputPositions() []token.Pos { 69 if e.err.Err == nil { 70 return nil 71 } 72 return e.err.Err.InputPositions() 73 } 74 75 func (e *valueError) Msg() (string, []interface{}) { 76 if e.err.Err == nil { 77 return "", nil 78 } 79 return e.err.Err.Msg() 80 } 81 82 func (e *valueError) Path() (a []string) { 83 if e.err.Err != nil { 84 a = e.err.Err.Path() 85 if a != nil { 86 return a 87 } 88 } 89 return pathToStrings(e.v.Path()) 90 } 91 92 var errNotExists = &adt.Bottom{ 93 Code: adt.IncompleteError, 94 NotExists: true, 95 Err: errors.Newf(token.NoPos, "undefined value"), 96 } 97 98 func mkErr(src adt.Node, args ...interface{}) *adt.Bottom { 99 var e *adt.Bottom 100 var code adt.ErrorCode = -1 101 outer: 102 for i, a := range args { 103 switch x := a.(type) { 104 case adt.ErrorCode: 105 code = x 106 case *adt.Bottom: 107 e = adt.CombineErrors(nil, e, x) 108 case []*adt.Bottom: 109 for _, b := range x { 110 e = adt.CombineErrors(nil, e, b) 111 } 112 case errors.Error: 113 e = adt.CombineErrors(nil, e, &adt.Bottom{Err: x}) 114 case adt.Expr: 115 case string: 116 args := args[i+1:] 117 // Do not expand message so that errors can be localized. 118 pos := pos(src) 119 if code < 0 { 120 code = 0 121 } 122 e = adt.CombineErrors(nil, e, &adt.Bottom{ 123 Code: code, 124 Err: errors.Newf(pos, x, args...), 125 }) 126 break outer 127 } 128 } 129 if code >= 0 { 130 e.Code = code 131 } 132 return e 133 }