cuelang.org/go@v0.10.1/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 "cuelang.org/go/internal/core/runtime" 22 ) 23 24 func (v Value) toErr(b *adt.Bottom) (err errors.Error) { 25 errs := errors.Errors(b.Err) 26 if len(errs) > 1 { 27 for _, e := range errs { 28 bb := *b 29 bb.Err = e 30 err = errors.Append(err, &valueError{v: v, err: &bb}) 31 } 32 return err 33 } 34 return &valueError{v: v, err: b} 35 } 36 37 var _ errors.Error = &valueError{} 38 39 // A valueError is returned as a result of evaluating a value. 40 type valueError struct { 41 v Value 42 err *adt.Bottom 43 } 44 45 func (e *valueError) Unwrap() error { 46 if e.err.Err == nil { 47 return nil 48 } 49 return errors.Unwrap(e.err.Err) 50 } 51 52 func (e *valueError) Bottom() *adt.Bottom { return e.err } 53 54 func (e *valueError) Error() string { 55 return errors.String(e) 56 } 57 58 func (e *valueError) Position() token.Pos { 59 if e.err.Err != nil { 60 return e.err.Err.Position() 61 } 62 src := e.err.Source() 63 if src == nil { 64 return token.NoPos 65 } 66 return src.Pos() 67 } 68 69 func (e *valueError) InputPositions() []token.Pos { 70 if e.err.Err == nil { 71 return nil 72 } 73 return e.err.Err.InputPositions() 74 } 75 76 func (e *valueError) Msg() (string, []interface{}) { 77 if e.err.Err == nil { 78 return "", nil 79 } 80 return e.err.Err.Msg() 81 } 82 83 func (e *valueError) Path() (a []string) { 84 if e.err.Err != nil { 85 a = e.err.Err.Path() 86 if a != nil { 87 return a 88 } 89 } 90 return pathToStrings(e.v.Path()) 91 } 92 93 var errNotExists = &adt.Bottom{ 94 Code: adt.IncompleteError, 95 NotExists: true, 96 Err: errors.Newf(token.NoPos, "undefined value"), 97 } 98 99 func mkErr(idx *runtime.Runtime, src adt.Node, args ...interface{}) *adt.Bottom { 100 var e *adt.Bottom 101 var code adt.ErrorCode = -1 102 outer: 103 for i, a := range args { 104 switch x := a.(type) { 105 case adt.ErrorCode: 106 code = x 107 case *adt.Bottom: 108 e = adt.CombineErrors(nil, e, x) 109 case []*adt.Bottom: 110 for _, b := range x { 111 e = adt.CombineErrors(nil, e, b) 112 } 113 case errors.Error: 114 e = adt.CombineErrors(nil, e, &adt.Bottom{Err: x}) 115 case adt.Expr: 116 case string: 117 args := args[i+1:] 118 // Do not expand message so that errors can be localized. 119 pos := pos(src) 120 if code < 0 { 121 code = 0 122 } 123 e = adt.CombineErrors(nil, e, &adt.Bottom{ 124 Code: code, 125 Err: errors.Newf(pos, x, args...), 126 }) 127 break outer 128 } 129 } 130 if code >= 0 { 131 e.Code = code 132 } 133 return e 134 }