this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

cue/errors: add Wrap

introduces new internal wrapping error that allows
harmonizing wrapped errors.

Issue #52

Change-Id: I93844d4cc7592521b70b6402a9670a941c2f6dfc
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/9447
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>

+113 -52
+1
cmd/cue/cmd/testdata/script/cmd_err.txt
··· 10 10 ./task_tool.cue:6:8 11 11 ./task_tool.cue:7:9 12 12 tool/file:15:3 13 + tool/file:15:16 13 14 -- task_tool.cue -- 14 15 package home 15 16
+1
cmd/cue/cmd/testdata/script/cmd_errpos.txt
··· 12 12 command.prompter.filename: invalid string argument: non-concrete value string: 13 13 ./task_tool.cue:9:10 14 14 tool/file:9:3 15 + tool/file:9:16 15 16 -- task_tool.cue -- 16 17 package foo 17 18
+1
cmd/cue/cmd/testdata/script/export_err.txt
··· 13 13 a.b.2.c: incomplete value int 14 14 out: invalid interpolation: undefined field d: 15 15 ./exporterr/export_err.cue:7:6 16 + ./exporterr/export_err.cue:7:16 16 17 -- expect-stdout -- 17 18 -- exporterr/export_err.cue -- 18 19 package exporterr
+1
cmd/cue/cmd/testdata/script/vet_yaml.txt
··· 4 4 -- expect-stderr -- 5 5 phrases: invalid value "phrases:\n # A quote from Mark Twain.\n quote1:\n lang: en\n attribution: Mark Twain\n\n # A Norwegian proverb.\n proverb:\n lang: no\n text: Stemmen som sier at du ikke klarer det, lyver." (does not satisfy encoding/yaml.Validate({phrases:{},#Phrase:{lang:=~"^[a-zA-Z0-9-_]{2,}$" | false,text:!=""},#LanguageTag:=~"^[a-zA-Z0-9-_]{2,}$" | false})): error in call to encoding/yaml.Validate: incomplete value !="": 6 6 ./yaml.cue:19:10 7 + ./yaml.cue:11:17 7 8 ./yaml.cue:21:10 8 9 -- yaml.cue -- 9 10 import "encoding/yaml"
+66 -30
cue/errors/errors.go
··· 170 170 // Wrapf creates an Error with the associated position and message. The provided 171 171 // error is added for inspection context. 172 172 func Wrapf(err error, p token.Pos, format string, args ...interface{}) Error { 173 - a, ok := err.(list) 173 + pErr := &posError{ 174 + pos: p, 175 + Message: NewMessage(format, args), 176 + } 177 + return Wrap(pErr, err) 178 + } 179 + 180 + // Wrap creates a new error where child is a subordinate error of parent. 181 + // If child is list of Errors, the result will itself be a list of errors 182 + // where child is a subordinate error of each parent. 183 + func Wrap(parent Error, child error) Error { 184 + if child == nil { 185 + return parent 186 + } 187 + a, ok := child.(list) 174 188 if !ok { 175 - return &posError{ 176 - pos: p, 177 - Message: NewMessage(format, args), 178 - err: err, 179 - } 189 + return &wrapped{parent, child} 180 190 } 181 - b := make([]Error, len(a)) 191 + b := make(list, len(a)) 182 192 for i, err := range a { 183 - b[i] = &posError{ 184 - pos: p, 185 - Message: NewMessage(format, args), 186 - err: err, 187 - } 193 + b[i] = &wrapped{parent, err} 188 194 } 189 - return list(b) 195 + return b 190 196 } 191 197 198 + type wrapped struct { 199 + main Error 200 + wrap error 201 + } 202 + 203 + // Error implements the error interface. 204 + func (e *wrapped) Error() string { 205 + switch msg := e.main.Error(); { 206 + case e.wrap == nil: 207 + return msg 208 + case msg == "": 209 + return e.wrap.Error() 210 + default: 211 + return fmt.Sprintf("%s: %s", msg, e.wrap) 212 + } 213 + } 214 + 215 + func (e *wrapped) Msg() (format string, args []interface{}) { 216 + return e.main.Msg() 217 + } 218 + 219 + func (e *wrapped) Path() []string { 220 + if p := Path(e.main); p != nil { 221 + return p 222 + } 223 + return Path(e.wrap) 224 + } 225 + 226 + func (e *wrapped) InputPositions() []token.Pos { 227 + return append(e.main.InputPositions(), Positions(e.wrap)...) 228 + } 229 + 230 + func (e *wrapped) Position() token.Pos { 231 + if p := e.main.Position(); p != token.NoPos { 232 + return p 233 + } 234 + if wrap, ok := e.wrap.(Error); ok { 235 + return wrap.Position() 236 + } 237 + return token.NoPos 238 + } 239 + 240 + func (e *wrapped) Unwrap() error { return e.wrap } 241 + 242 + func (e *wrapped) Cause() error { return e.wrap } 243 + 192 244 // Promote converts a regular Go error to an Error if it isn't already one. 193 245 func Promote(err error, msg string) Error { 194 246 switch x := err.(type) { ··· 209 261 pos token.Pos 210 262 inputs []token.Pos 211 263 Message 212 - 213 - // The underlying error that triggered this one, if any. 214 - err error 215 264 } 216 265 217 - func (e *posError) Path() []string { return Path(e.err) } 266 + func (e *posError) Path() []string { return nil } 218 267 func (e *posError) InputPositions() []token.Pos { return e.inputs } 219 268 func (e *posError) Position() token.Pos { return e.pos } 220 - func (e *posError) Unwrap() error { return e.err } 221 - func (e *posError) Cause() error { return e.err } 222 - 223 - // Error implements the error interface. 224 - func (e *posError) Error() string { 225 - if e.err == nil { 226 - return e.Message.Error() 227 - } 228 - if e.Message.format == "" { 229 - return e.err.Error() 230 - } 231 - return fmt.Sprintf("%s: %s", e.Message.Error(), e.err) 232 - } 233 269 234 270 // Append combines two errors, flattening Lists as necessary. 235 271 func Append(a, b Error) Error {
+4
cue/testdata/eval/dynamic_field.txtar
··· 25 25 Errors: 26 26 invalid interpolation: conflicting values 2 and 1: 27 27 ./in.cue:12:31 28 + ./in.cue:12:34 29 + ./in.cue:12:36 28 30 29 31 Result: 30 32 (_|_){ ··· 40 42 issue799: (_|_){ 41 43 // [eval] invalid interpolation: conflicting values 2 and 1: 42 44 // ./in.cue:12:31 45 + // ./in.cue:12:34 46 + // ./in.cue:12:36 43 47 key: (int){ &(>=-2147483648, <=2147483647, int) } 44 48 } 45 49 }
+4
cue/testdata/fulleval/055_issue318.txtar
··· 45 45 Errors: 46 46 #T.out1: invalid interpolation: undefined field y: 47 47 ./in.cue:3:8 48 + ./in.cue:3:24 48 49 #T.out2: invalid interpolation: undefined field y: 49 50 ./in.cue:4:8 51 + ./in.cue:4:15 50 52 #T.vy: undefined field y: 51 53 ./in.cue:6:12 52 54 ··· 61 63 out1: (_|_){ 62 64 // [eval] #T.out1: invalid interpolation: undefined field y: 63 65 // ./in.cue:3:8 66 + // ./in.cue:3:24 64 67 } 65 68 out2: (_|_){ 66 69 // [eval] #T.out2: invalid interpolation: undefined field y: 67 70 // ./in.cue:4:8 71 + // ./in.cue:4:15 68 72 } 69 73 vx: (string){ string } 70 74 vy: (_|_){
+3
cue/testdata/interpolation/041_interpolation.txtar
··· 35 35 Errors: 36 36 e: invalid interpolation: cannot use [] (type list) as type (bool|string|bytes|number): 37 37 ./in.cue:7:4 38 + ./in.cue:7:7 38 39 39 40 Result: 40 41 (_|_){ ··· 49 50 u: (_|_){ 50 51 // [incomplete] u: invalid interpolation: non-concrete value _ (type _): 51 52 // ./in.cue:5:4 53 + // ./in.cue:5:7 52 54 } 53 55 r: (_){ _ } 54 56 e: (_|_){ 55 57 // [eval] e: invalid interpolation: cannot use [] (type list) as type (bool|string|bytes|number): 56 58 // ./in.cue:7:4 59 + // ./in.cue:7:7 57 60 } 58 61 }
+1
cue/testdata/interpolation/incomplete.txtar
··· 27 27 out: (_|_){ 28 28 // [incomplete] out: invalid interpolation: undefined field #d: 29 29 // ./in.cue:8:6 30 + // ./in.cue:13:21 30 31 } 31 32 } 32 33 -- out/compile --
+2
cue/testdata/references/errors.txtar
··· 80 80 r1: (_|_){ 81 81 // [incomplete] missingFieldNestedInInterpolation.r1: invalid interpolation: undefined field b: 82 82 // ./references.cue:27:9 83 + // ./references.cue:27:14 83 84 } 84 85 r2: (_|_){ 85 86 // [incomplete] missingFieldNestedInInterpolation.r2: invalid interpolation: undefined field d: 86 87 // ./references.cue:30:9 88 + // ./references.cue:30:14 87 89 } 88 90 } 89 91 }
-5
internal/core/adt/errors.go
··· 211 211 v *Vertex 212 212 pos token.Pos 213 213 auxpos []token.Pos 214 - err errors.Error 215 214 errors.Message 216 215 } 217 216 ··· 325 324 } 326 325 return a 327 326 } 328 - 329 - func (e ValueError) Unwrap() error { 330 - return e.err 331 - }
+1 -2
internal/core/adt/expr.go
··· 1484 1484 } 1485 1485 1486 1486 vErr := c.NewPosf(src, "invalid value %s (does not satisfy %s)", args[0], buf.String()) 1487 - vErr.err = err 1488 1487 1489 1488 for _, v := range args { 1490 1489 vErr.AddPosition(v) 1491 1490 } 1492 1491 1493 - return &Bottom{Code: severeness, Err: vErr} 1492 + return &Bottom{Code: severeness, Err: errors.Wrap(vErr, err)} 1494 1493 } 1495 1494 1496 1495 // A Disjunction represents a disjunction, where each disjunct may or may not
+1 -5
internal/task/task.go
··· 88 88 task: c.Obj, 89 89 v: v, 90 90 Message: errors.NewMessage(format, args), 91 - err: wrap, 92 91 } 93 - c.Err = errors.Append(c.Err, err) 92 + c.Err = errors.Append(c.Err, errors.Wrap(err, wrap)) 94 93 } 95 94 96 95 // taskError wraps some error values to retain position information about the ··· 99 98 task cue.Value 100 99 v cue.Value 101 100 errors.Message 102 - err error 103 101 } 104 102 105 103 var _ errors.Error = &taskError{} ··· 125 123 } 126 124 return a 127 125 } 128 - 129 - func (t *taskError) Unwrap() error { return t.err } 130 126 131 127 // A RunnerFunc creates a Runner. 132 128 type RunnerFunc func(v cue.Value) (Runner, error)
+3 -1
pkg/encoding/json/testdata/gen.txtar
··· 17 17 t9: json.MarshalStream([{a: 1}, {b: int | *2}]) 18 18 -- out/json -- 19 19 Errors: 20 - a: error in call to encoding/json.Validate: invalid value 10 (out of bound <3) 20 + a: error in call to encoding/json.Validate: invalid value 10 (out of bound <3): 21 + ./in.cue:4:36 22 + json.Validate:1:6 21 23 22 24 Result: 23 25 import "encoding/json"
+6 -2
pkg/encoding/yaml/testdata/gen.txtar
··· 14 14 t9: yaml.MarshalStream([{a: 1}, {b: int | *2}]) 15 15 -- out/yaml -- 16 16 Errors: 17 - a: error in call to encoding/yaml.Validate: invalid value 4 (out of bound <3) 18 - a: error in call to encoding/yaml.ValidatePartial: invalid value 4 (out of bound <3) 19 17 b: error in call to encoding/yaml.Validate: incomplete value int 18 + a: error in call to encoding/yaml.Validate: invalid value 4 (out of bound <3): 19 + ./in.cue:3:41 20 + yaml.Validate:3:5 21 + a: error in call to encoding/yaml.ValidatePartial: invalid value 4 (out of bound <3): 22 + ./in.cue:6:48 23 + yaml.ValidatePartial:3:5 20 24 21 25 Result: 22 26 t1: _|_ // error in call to encoding/yaml.Validate: a: invalid value 4 (out of bound <3) (and 1 more errors)
+14 -5
pkg/list/testdata/gen.txtar
··· 65 65 Errors: 66 66 error in call to list.Avg: empty list 67 67 error in call to list.Drop: negative index 68 - error in call to list.FlattenN: cannot use value "foo" (type string) as list 69 68 error in call to list.Max: empty list 70 69 error in call to list.Min: empty list 71 70 error in call to list.Range: end must be greater than start when step is positive ··· 76 75 error in call to list.Slice: slice bounds out of range 77 76 error in call to list.Take: negative index 78 77 Ascending.x: error in call to list.Sort: 2 errors in empty disjunction: 79 - Ascending.x: error in call to list.Sort: conflicting values number and {b:2} (mismatched types number and struct) 80 - Ascending.x: error in call to list.Sort: conflicting values string and {b:2} (mismatched types string and struct) 78 + Ascending.x: error in call to list.Sort: conflicting values number and {b:2} (mismatched types number and struct): 79 + ./in.cue:46:24 80 + list:10:9 81 + Ascending.x: error in call to list.Sort: conflicting values string and {b:2} (mismatched types string and struct): 82 + ./in.cue:46:24 83 + list:10:18 81 84 Ascending.y: error in call to list.Sort: 2 errors in empty disjunction: 82 - Ascending.y: error in call to list.Sort: conflicting values number and {a:1} (mismatched types number and struct) 83 - Ascending.y: error in call to list.Sort: conflicting values string and {a:1} (mismatched types string and struct) 85 + Ascending.y: error in call to list.Sort: conflicting values number and {a:1} (mismatched types number and struct): 86 + ./in.cue:46:17 87 + list:10:9 88 + Ascending.y: error in call to list.Sort: conflicting values string and {a:1} (mismatched types string and struct): 89 + ./in.cue:60:17 90 + list:10:18 84 91 t3: cannot use "foo" (type string) as list in argument 1 to list.Avg: 85 92 ./in.cue:5:14 93 + error in call to list.FlattenN: cannot use value "foo" (type string) as list: 94 + ./in.cue:15:20 86 95 t14: cannot use "foo" (type string) as int in argument 2 to list.FlattenN: 87 96 ./in.cue:16:24 88 97 t17: cannot use "foo" (type string) as list in argument 1 to list.Max:
+2 -1
pkg/list/testdata/list.txtar
··· 43 43 } 44 44 -- out/list -- 45 45 Errors: 46 - error in call to list.Concat: cannot use value 1 (type int) as list 47 46 error in call to list.Repeat: negative count 48 47 concat.t7.v: cannot use 1 (type int) as list in argument 1 to list.Concat: 49 48 ./in.cue:30:12 49 + error in call to list.Concat: cannot use value 1 (type int) as list: 50 + ./in.cue:31:13 50 51 51 52 Result: 52 53 repeat: {
+2 -1
pkg/math/testdata/gen.txtar
··· 25 25 t33: math.Dim(5, 7.2) 26 26 -- out/math -- 27 27 Errors: 28 - error in call to math.Jacobi: big: invalid 2nd argument to Int.Jacobi: need odd integer but got 2000 29 28 t3: cannot call non-function math.Pi (type float): 30 29 ./in.cue:5:5 30 + error in call to math.Jacobi: big: invalid 2nd argument to Int.Jacobi: need odd integer but got 2000: 31 + ./in.cue:6:5 31 32 cannot use 2.0E+400 (type float) as float64 in argument 0 to math.Asin: value was rounded up: 32 33 ./in.cue:8:5 33 34