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  }