OLD | NEW |
1 // Copyright 2015 The LUCI Authors. All rights reserved. | 1 // Copyright 2015 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 errors | 5 package errors |
6 | 6 |
7 import ( | 7 import ( |
8 "fmt" | 8 "fmt" |
9 "reflect" | |
10 ) | |
11 | |
12 var ( | |
13 multiErrorType = reflect.TypeOf(MultiError(nil)) | |
14 ) | 9 ) |
15 | 10 |
16 // MultiError is a simple `error` implementation which represents multiple | 11 // MultiError is a simple `error` implementation which represents multiple |
17 // `error` objects in one. | 12 // `error` objects in one. |
18 type MultiError []error | 13 type MultiError []error |
19 | 14 |
20 func (m MultiError) Error() string { | 15 func (m MultiError) Error() string { |
21 n, e := m.Summary() | 16 n, e := m.Summary() |
22 switch n { | 17 switch n { |
23 case 0: | 18 case 0: |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 // If err is a MultiError, return its first element. Otherwise, return err. | 75 // If err is a MultiError, return its first element. Otherwise, return err. |
81 func SingleError(err error) error { | 76 func SingleError(err error) error { |
82 if me, ok := err.(MultiError); ok { | 77 if me, ok := err.(MultiError); ok { |
83 if len(me) == 0 { | 78 if len(me) == 0 { |
84 return nil | 79 return nil |
85 } | 80 } |
86 return me[0] | 81 return me[0] |
87 } | 82 } |
88 return err | 83 return err |
89 } | 84 } |
90 | |
91 // MultiErrorFromErrors takes an error-channel, blocks on it, and returns | |
92 // a MultiError for any errors pushed to it over the channel, or nil if | |
93 // all the errors were nil. | |
94 func MultiErrorFromErrors(ch <-chan error) error { | |
95 if ch == nil { | |
96 return nil | |
97 } | |
98 ret := MultiError(nil) | |
99 for e := range ch { | |
100 if e == nil { | |
101 continue | |
102 } | |
103 ret = append(ret, e) | |
104 } | |
105 if len(ret) == 0 { | |
106 return nil | |
107 } | |
108 return ret | |
109 } | |
110 | |
111 // Fix will convert a MultiError compatible type (e.g. []error) to this | |
112 // version of MultiError. | |
113 func Fix(err error) error { | |
114 if err != nil { | |
115 // we know that err already conforms to the error interface (or
the caller's | |
116 // method wouldn't compile), so check to see if the error's unde
rlying type | |
117 // looks like one of the special error types we implement. | |
118 v := reflect.ValueOf(err) | |
119 if v.Type().ConvertibleTo(multiErrorType) { | |
120 err = v.Convert(multiErrorType).Interface().(error) | |
121 } | |
122 } | |
123 return err | |
124 } | |
OLD | NEW |