github.com/insolar/vanilla@v0.0.0-20201023172447-248fdf805322/throw/severe.go (about) 1 // Copyright 2020 Insolar Network Ltd. 2 // All rights reserved. 3 // This material is licensed under the Insolar License version 1.0, 4 // available at https://github.com/insolar/assured-ledger/blob/master/LICENSE.md. 5 6 package throw 7 8 import "errors" 9 10 type Severity uint8 11 12 const ( 13 _ Severity = iota 14 // NormalSeverity should only be used to override higher severity levels with WithSeverity 15 NormalSeverity 16 17 // BlameSeverity indicates an attempt of a remote peer to compromise stability/performance of a peer network, 18 // but there is no non-reputable proof available/possible, or multiple evidences from multiple peers are required. 19 BlameSeverity 20 21 // ViolationSeverity indicates an attempt of a remote peer to use an incorrect encoding / protocol combination that 22 // can't compromise stability or performance of a peer network. 23 ViolationSeverity 24 25 // FraudSeverity indicates an attempt of a remote peer to compromise stability/performance of a peer network. 26 // This severity can only be declared when there is either a non-reputable proof or a network majority proof. 27 FraudSeverity 28 29 // RemoteBreachSeverity indicates a presence of either security breach on a remote peer or MitM attack. 30 // Connection to the peer must be terminated, and the peer may need to be quarantined / blacklisted. 31 RemoteBreachSeverity 32 33 // LocalBreachSeverity indicates a presence of local security breach. Application must be terminated or quarantined asap. 34 LocalBreachSeverity 35 36 // FatalSeverity indicates an error that requires an application to be terminated asap for a reason unknown. 37 FatalSeverity 38 ) 39 40 func (v Severity) IsFatal() bool { 41 return v >= LocalBreachSeverity 42 } 43 44 func (v Severity) IsError() bool { 45 return v > RemoteBreachSeverity 46 } 47 48 func (v Severity) IsWarn() bool { 49 return v > NormalSeverity 50 } 51 52 func (v Severity) IsDeadCanary() bool { 53 return v >= LocalBreachSeverity 54 } 55 56 func (v Severity) IsCompromised() bool { 57 return v >= RemoteBreachSeverity 58 } 59 60 func (v Severity) IsFraudOrWorse() bool { 61 return v >= FraudSeverity 62 } 63 64 func Blame(msg string, description ...interface{}) error { 65 return Severe(BlameSeverity, msg, description...) 66 } 67 68 func Violation(msg string, description ...interface{}) error { 69 return Severe(ViolationSeverity, msg, description...) 70 } 71 72 func Fraud(msg string, description ...interface{}) error { 73 return Severe(FraudSeverity, msg, description...) 74 } 75 76 func RemoteBreach(msg string, description ...interface{}) error { 77 return Severe(RemoteBreachSeverity, msg, description...) 78 } 79 80 func LocalBreach(msg string, description ...interface{}) error { 81 return Severe(LocalBreachSeverity, msg, description...) 82 } 83 84 func DeadCanary(msg string, description ...interface{}) error { 85 return Severe(LocalBreachSeverity, msg, description...) 86 } 87 88 func Fatal(msg string, description ...interface{}) error { 89 return Severe(FatalSeverity, msg, description...) 90 } 91 92 func WithSeverity(err error, s Severity) error { 93 switch { 94 case s == 0: 95 return err 96 case err == nil: 97 return nil 98 default: 99 return severityWrap{err, s} 100 } 101 } 102 103 func WithDefaultSeverity(err error, s Severity) error { 104 switch { 105 case s == 0: 106 return err 107 case err == nil: 108 return nil 109 default: 110 if _, ok := GetSeverity(err); ok { 111 return err 112 } 113 return severityWrap{err, s} 114 } 115 } 116 117 func WithEscalatedSeverity(err error, s Severity) error { 118 switch { 119 case s == 0: 120 return err 121 case err == nil: 122 return nil 123 default: 124 sv, _ := GetSeverity(err) 125 if sv >= s { 126 return err 127 } 128 return severityWrap{err, s} 129 } 130 } 131 132 func SeverityOf(errChain error) Severity { 133 s, _ := GetSeverity(errChain) 134 return s 135 } 136 137 func GetSeverity(errChain error) (Severity, bool) { 138 for errChain != nil { 139 var s Severity 140 switch v := errChain.(type) { 141 case fmtWrap: 142 s = v.severity 143 case panicWrap: 144 s = v.severity 145 case severityWrap: 146 return v.severity, true 147 } 148 if s != 0 { 149 return s, true 150 } 151 errChain = errors.Unwrap(errChain) 152 } 153 return NormalSeverity, false 154 }