github.com/m3db/m3@v1.5.0/src/query/storage/error_behavior.go (about) 1 // Copyright (c) 2019 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package storage 22 23 import "fmt" 24 25 var ( 26 // NB: Container behavior must not be defined in configs, so it does not count 27 // as a parsable behavior. This is because it's a composite storage type that 28 // refers to fanout storage, and requires further parsing to determine error 29 // behavior. 30 parsableErrorBehaviors = []ErrorBehavior{ 31 BehaviorFail, 32 BehaviorWarn, 33 } 34 ) 35 36 func (e ErrorBehavior) String() string { 37 switch e { 38 case BehaviorFail: 39 return "fail" 40 case BehaviorWarn: 41 return "warn" 42 case BehaviorContainer: 43 return "container" 44 default: 45 return "unknown" 46 } 47 } 48 49 // ParseErrorBehavior parses an error behavior. 50 func ParseErrorBehavior(str string) (ErrorBehavior, error) { 51 for _, valid := range parsableErrorBehaviors { 52 if str == valid.String() { 53 return valid, nil 54 } 55 } 56 57 return 0, fmt.Errorf("unrecognized error behavior: %v", str) 58 } 59 60 // UnmarshalYAML unmarshals an error behavior. 61 func (e *ErrorBehavior) UnmarshalYAML(unmarshal func(interface{}) error) error { 62 var str string 63 if err := unmarshal(&str); err != nil { 64 return err 65 } 66 67 if value, err := ParseErrorBehavior(str); err == nil { 68 *e = value 69 return nil 70 } 71 72 return fmt.Errorf("invalid ErrorBehavior '%s' valid types are: %v", 73 str, parsableErrorBehaviors) 74 } 75 76 // IsWarning determines if the given error coming from the storage is a warning, 77 // and returns it with appropriate wrapping. 78 func IsWarning(store Storage, err error) (bool, error) { 79 if _, ok := err.(warnError); ok { 80 return true, err 81 } 82 83 if store.ErrorBehavior() == BehaviorWarn { 84 return true, warnError{err} 85 } 86 87 return false, err 88 } 89 90 // warnError is an error that should only warn on failure. 91 type warnError struct { 92 inner error 93 } 94 95 func (e warnError) Error() string { 96 return e.inner.Error() 97 }