OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package errors | 5 package errors |
6 | 6 |
7 import ( | 7 import ( |
8 "fmt" | 8 "fmt" |
9 "reflect" | 9 "reflect" |
10 "sync" | |
11 ) | 10 ) |
12 | 11 |
13 var ( | 12 var ( |
14 multiErrorType = reflect.TypeOf(MultiError(nil)) | 13 multiErrorType = reflect.TypeOf(MultiError(nil)) |
15 ) | 14 ) |
16 | 15 |
17 // MultiError is a simple `error` implementation which represents multiple | 16 // MultiError is a simple `error` implementation which represents multiple |
18 // `error` objects in one. | 17 // `error` objects in one. |
19 type MultiError []error | 18 type MultiError []error |
20 | 19 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 continue | 65 continue |
67 } | 66 } |
68 ret = append(ret, e) | 67 ret = append(ret, e) |
69 } | 68 } |
70 if len(ret) == 0 { | 69 if len(ret) == 0 { |
71 return nil | 70 return nil |
72 } | 71 } |
73 return ret | 72 return ret |
74 } | 73 } |
75 | 74 |
76 // LazyMultiError is a lazily-constructed MultiError. You specify the target | |
77 // MultiError size up front (as Size), and then you call Assign for each error | |
78 // encountered, and it's potential index. The MultiError will only be allocated | |
79 // if one of the Assign'd errors is non-nil. Similarly, Get will retrieve either | |
80 // the allocated MultiError, or nil if no error was encountered. | |
81 type LazyMultiError struct { | |
82 sync.Mutex | |
83 | |
84 Size int | |
85 me MultiError | |
86 } | |
87 | |
88 // Assign semantically assigns the error to the given index in the MultiError. | |
89 // If the error is nil, no action is taken. Otherwise the MultiError is | |
90 // allocated to its full size (if not already), and the error assigned into it. | |
91 // | |
92 // It returns true iff err != nil. | |
93 func (e *LazyMultiError) Assign(i int, err error) bool { | |
94 if err == nil { | |
95 return false | |
96 } | |
97 e.Lock() | |
98 defer e.Unlock() | |
99 if e.me == nil { | |
100 e.me = make(MultiError, e.Size) | |
101 } | |
102 e.me[i] = err | |
103 return true | |
104 } | |
105 | |
106 // GetOne returns the error at the given index, or nil, if no non-nil error | |
107 // was Assign'd. | |
108 func (e *LazyMultiError) GetOne(i int) error { | |
109 e.Lock() | |
110 defer e.Unlock() | |
111 if e.me == nil { | |
112 return nil | |
113 } | |
114 return e.me[i] | |
115 } | |
116 | |
117 // Get returns the MultiError, or nil, if no non-nil error was Assign'd. | |
118 func (e *LazyMultiError) Get() error { | |
119 e.Lock() | |
120 defer e.Unlock() | |
121 if e.me == nil { | |
122 return nil | |
123 } | |
124 return e.me | |
125 } | |
126 | |
127 // Fix will convert a MultiError compatible type (e.g. []error) to this | 75 // Fix will convert a MultiError compatible type (e.g. []error) to this |
128 // version of MultiError. | 76 // version of MultiError. |
129 func Fix(err error) error { | 77 func Fix(err error) error { |
130 if err != nil { | 78 if err != nil { |
131 // we know that err already conforms to the error interface (or
the caller's | 79 // we know that err already conforms to the error interface (or
the caller's |
132 // method wouldn't compile), so check to see if the error's unde
rlying type | 80 // method wouldn't compile), so check to see if the error's unde
rlying type |
133 // looks like one of the special error types we implement. | 81 // looks like one of the special error types we implement. |
134 v := reflect.ValueOf(err) | 82 v := reflect.ValueOf(err) |
135 if v.Type().ConvertibleTo(multiErrorType) { | 83 if v.Type().ConvertibleTo(multiErrorType) { |
136 err = v.Convert(multiErrorType).Interface().(error) | 84 err = v.Convert(multiErrorType).Interface().(error) |
137 } | 85 } |
138 } | 86 } |
139 return err | 87 return err |
140 } | 88 } |
OLD | NEW |