github.com/Uhtred009/v2ray-core-1@v4.31.2+incompatible/common/errors/errors.go (about) 1 // Package errors is a drop-in replacement for Golang lib 'errors'. 2 package errors // import "v2ray.com/core/common/errors" 3 4 import ( 5 "os" 6 "reflect" 7 "strings" 8 9 "v2ray.com/core/common/log" 10 "v2ray.com/core/common/serial" 11 ) 12 13 type hasInnerError interface { 14 // Inner returns the underlying error of this one. 15 Inner() error 16 } 17 18 type hasSeverity interface { 19 Severity() log.Severity 20 } 21 22 // Error is an error object with underlying error. 23 type Error struct { 24 pathObj interface{} 25 prefix []interface{} 26 message []interface{} 27 inner error 28 severity log.Severity 29 } 30 31 func (err *Error) WithPathObj(obj interface{}) *Error { 32 err.pathObj = obj 33 return err 34 } 35 36 func (err *Error) pkgPath() string { 37 if err.pathObj == nil { 38 return "" 39 } 40 return reflect.TypeOf(err.pathObj).PkgPath() 41 } 42 43 // Error implements error.Error(). 44 func (err *Error) Error() string { 45 builder := strings.Builder{} 46 for _, prefix := range err.prefix { 47 builder.WriteByte('[') 48 builder.WriteString(serial.ToString(prefix)) 49 builder.WriteString("] ") 50 } 51 52 path := err.pkgPath() 53 if len(path) > 0 { 54 builder.WriteString(path) 55 builder.WriteString(": ") 56 } 57 58 msg := serial.Concat(err.message...) 59 builder.WriteString(msg) 60 61 if err.inner != nil { 62 builder.WriteString(" > ") 63 builder.WriteString(err.inner.Error()) 64 } 65 66 return builder.String() 67 } 68 69 // Inner implements hasInnerError.Inner() 70 func (err *Error) Inner() error { 71 if err.inner == nil { 72 return nil 73 } 74 return err.inner 75 } 76 77 func (err *Error) Base(e error) *Error { 78 err.inner = e 79 return err 80 } 81 82 func (err *Error) atSeverity(s log.Severity) *Error { 83 err.severity = s 84 return err 85 } 86 87 func (err *Error) Severity() log.Severity { 88 if err.inner == nil { 89 return err.severity 90 } 91 92 if s, ok := err.inner.(hasSeverity); ok { 93 as := s.Severity() 94 if as < err.severity { 95 return as 96 } 97 } 98 99 return err.severity 100 } 101 102 // AtDebug sets the severity to debug. 103 func (err *Error) AtDebug() *Error { 104 return err.atSeverity(log.Severity_Debug) 105 } 106 107 // AtInfo sets the severity to info. 108 func (err *Error) AtInfo() *Error { 109 return err.atSeverity(log.Severity_Info) 110 } 111 112 // AtWarning sets the severity to warning. 113 func (err *Error) AtWarning() *Error { 114 return err.atSeverity(log.Severity_Warning) 115 } 116 117 // AtError sets the severity to error. 118 func (err *Error) AtError() *Error { 119 return err.atSeverity(log.Severity_Error) 120 } 121 122 // String returns the string representation of this error. 123 func (err *Error) String() string { 124 return err.Error() 125 } 126 127 // WriteToLog writes current error into log. 128 func (err *Error) WriteToLog(opts ...ExportOption) { 129 var holder ExportOptionHolder 130 131 for _, opt := range opts { 132 opt(&holder) 133 } 134 135 if holder.SessionID > 0 { 136 err.prefix = append(err.prefix, holder.SessionID) 137 } 138 139 log.Record(&log.GeneralMessage{ 140 Severity: GetSeverity(err), 141 Content: err, 142 }) 143 } 144 145 type ExportOptionHolder struct { 146 SessionID uint32 147 } 148 149 type ExportOption func(*ExportOptionHolder) 150 151 // New returns a new error object with message formed from given arguments. 152 func New(msg ...interface{}) *Error { 153 return &Error{ 154 message: msg, 155 severity: log.Severity_Info, 156 } 157 } 158 159 // Cause returns the root cause of this error. 160 func Cause(err error) error { 161 if err == nil { 162 return nil 163 } 164 L: 165 for { 166 switch inner := err.(type) { 167 case hasInnerError: 168 if inner.Inner() == nil { 169 break L 170 } 171 err = inner.Inner() 172 case *os.PathError: 173 if inner.Err == nil { 174 break L 175 } 176 err = inner.Err 177 case *os.SyscallError: 178 if inner.Err == nil { 179 break L 180 } 181 err = inner.Err 182 default: 183 break L 184 } 185 } 186 return err 187 } 188 189 // GetSeverity returns the actual severity of the error, including inner errors. 190 func GetSeverity(err error) log.Severity { 191 if s, ok := err.(hasSeverity); ok { 192 return s.Severity() 193 } 194 return log.Severity_Info 195 }