github.com/solo-io/cue@v0.4.7/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 "github.com/solo-io/cue/cue/errors" 19 "github.com/solo-io/cue/cue/token" 20 "github.com/solo-io/cue/internal/core/adt" 21 "github.com/solo-io/cue/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.NotExistError, 95 Err: errors.Newf(token.NoPos, "undefined value"), 96 } 97 98 func mkErr(idx *runtime.Runtime, 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 }