go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/common/errors/filter.go (about) 1 // Copyright 2016 The LUCI 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 errors 16 17 // Filter examines a supplied error and removes instances of excluded errors 18 // from it. If the entire supplied error is excluded, Filter will return nil. 19 // 20 // If a MultiError is supplied to Filter, it will be recursively traversed, and 21 // its child errors will be turned into nil if they match the supplied filter. 22 // If a MultiError has all of its children converted to nil as a result of the 23 // filter, it will itself be reduced to nil. 24 func Filter(err error, exclude error, others ...error) error { 25 return FilterFunc(err, func(e error) bool { 26 if e == exclude { 27 return true 28 } 29 for _, v := range others { 30 if e == v { 31 return true 32 } 33 } 34 return false 35 }) 36 } 37 38 // FilterFunc examines a supplied error and removes instances of errors that 39 // match the supplied filter function. If the entire supplied error is removed, 40 // FilterFunc will return nil. 41 // 42 // If a MultiError is supplied to FilterFunc, it will be recursively traversed, 43 // and its child errors will be turned into nil if they match the supplied 44 // filter function. If a MultiError has all of its children converted to nil as 45 // a result of the filter, it will itself be reduced to nil. 46 // 47 // Consqeuently, if err is a MultiError, shouldFilter will be called once with 48 // err as its value and once for every non-nil error that it contains. 49 func FilterFunc(err error, shouldFilter func(error) bool) error { 50 switch { 51 case shouldFilter == nil: 52 return err 53 case err == nil: 54 return nil 55 case shouldFilter(err): 56 return nil 57 } 58 59 if merr, ok := err.(MultiError); ok { 60 var lme MultiError 61 for i, e := range merr { 62 if e != nil { 63 e = FilterFunc(e, shouldFilter) 64 if e != nil { 65 if lme == nil { 66 lme = make(MultiError, len(merr)) 67 } 68 lme[i] = e 69 } 70 } 71 } 72 if lme == nil { 73 return nil 74 } 75 return lme 76 } 77 78 return err 79 }