Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1159)

Side by Side Diff: common/config/validation/validation.go

Issue 2951393002: [errors] de-specialize Transient in favor of Tags. (Closed)
Patch Set: copyright Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2017 The LUCI Authors. All rights reserved. 1 // Copyright 2017 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0 2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file. 3 // that can be found in the LICENSE file.
4 4
5 // Package validation provides a helper for performing config validations. 5 // Package validation provides a helper for performing config validations.
6 package validation 6 package validation
7 7
8 import ( 8 import (
9 "fmt" 9 "fmt"
10 "strings" 10 "strings"
(...skipping 26 matching lines...) Expand all
37 // now). Each file may have some internal nested structure. The logical path 37 // now). Each file may have some internal nested structure. The logical path
38 // inside this structure is captured through Enter and Exit calls. 38 // inside this structure is captured through Enter and Exit calls.
39 type Context struct { 39 type Context struct {
40 Logger logging.Logger // logs errors as they appear 40 Logger logging.Logger // logs errors as they appear
41 41
42 errors errors.MultiError // all accumulated errors 42 errors errors.MultiError // all accumulated errors
43 file string // the currently validated file 43 file string // the currently validated file
44 element []string // logical path of a sub-element we validate, see Enter 44 element []string // logical path of a sub-element we validate, see Enter
45 } 45 }
46 46
47 var fileTag = errors.NewTagger("holds the file name for tests")
48 var element0Tag = errors.NewTagger("holds the first element for tests")
49
47 // Error records a validation error. 50 // Error records a validation error.
48 func (v *Context) Error(msg string, args ...interface{}) { 51 func (v *Context) Error(msg string, args ...interface{}) {
49 ctx := "" 52 ctx := ""
50 if v.file != "" { 53 if v.file != "" {
51 ctx = fmt.Sprintf("in %q", v.file) 54 ctx = fmt.Sprintf("in %q", v.file)
52 } else { 55 } else {
53 ctx = "in <unspecified file>" 56 ctx = "in <unspecified file>"
54 } 57 }
58 tags := []errors.TagValue{fileTag.With(v.file)}
55 if len(v.element) != 0 { 59 if len(v.element) != 0 {
60 tags = append(tags, element0Tag.With(v.element[0]))
56 ctx += " (" + strings.Join(v.element, " / ") + ")" 61 ctx += " (" + strings.Join(v.element, " / ") + ")"
57 } 62 }
58 63
59 // Prepending ctx to msg before passing it to fmt is not entirely correc t, 64 // Prepending ctx to msg before passing it to fmt is not entirely correc t,
60 // since ctx may have format specifiers (like %s), that will be misunder stood. 65 // since ctx may have format specifiers (like %s), that will be misunder stood.
61 // So we put ctx in the argument list. 66 // So we put ctx in the argument list.
62 msg = "%s: " + msg 67 msg = "%s: " + msg
63 args = append([]interface{}{ctx}, args...) 68 args = append([]interface{}{ctx}, args...)
64 if v.Logger != nil { 69 if v.Logger != nil {
65 v.Logger.Errorf(msg, args...) 70 v.Logger.Errorf(msg, args...)
66 } 71 }
67 72
68 // Make the file and the logical path also usable through error inspecti on. 73 // Make the file and the logical path also usable through error inspecti on.
69 » err := errors.Reason(fmt.Sprintf(msg, args...)). 74 » err := errors.Reason(fmt.Sprintf(msg, args...)).Tag(tags...).Err()
70 » » D("file", v.file).
71 » » D("element", append([]string{}, v.element...)).Err()
72 v.errors = append(v.errors, err) 75 v.errors = append(v.errors, err)
73 } 76 }
74 77
75 // SetFile records that what follows is errors for this particular file. 78 // SetFile records that what follows is errors for this particular file.
76 // 79 //
77 // Changing the file resets the current element (see Enter/Exit). 80 // Changing the file resets the current element (see Enter/Exit).
78 func (v *Context) SetFile(path string) { 81 func (v *Context) SetFile(path string) {
79 if v.file != path { 82 if v.file != path {
80 v.file = path 83 v.file = path
81 v.element = nil 84 v.element = nil
(...skipping 25 matching lines...) Expand all
107 // 110 //
108 // Returns nil otherwise. 111 // Returns nil otherwise.
109 func (v *Context) Finalize() error { 112 func (v *Context) Finalize() error {
110 if len(v.errors) == 0 { 113 if len(v.errors) == 0 {
111 return nil 114 return nil
112 } 115 }
113 return &Error{ 116 return &Error{
114 Errors: append(errors.MultiError{}, v.errors...), 117 Errors: append(errors.MultiError{}, v.errors...),
115 } 118 }
116 } 119 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698