github.com/insolar/vanilla@v0.0.0-20201023172447-248fdf805322/throw/wraps.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 ( 9 "errors" 10 ) 11 12 type msgWrap struct { 13 st StackTrace 14 msg string 15 } 16 17 func (v msgWrap) Cause() error { 18 return errString(v.msg) 19 } 20 21 func (v msgWrap) ShallowStackTrace() StackTrace { 22 return v.st 23 } 24 25 func (v msgWrap) DeepestStackTrace() (StackTrace, DeepestStackMode) { 26 return v.st, 0 27 } 28 29 func (v msgWrap) ExtraInfo() (string, Severity, interface{}) { 30 return v.msg, 0, nil 31 } 32 33 func (v msgWrap) LogString() string { 34 return v.msg 35 } 36 37 func (v msgWrap) Error() string { 38 return v.msg 39 } 40 41 type errString string 42 43 func (v errString) Error() string { 44 return string(v) 45 } 46 47 func joinErrString(s0, s1 string) string { 48 switch { 49 case s0 == "": 50 return s1 51 case s1 == "": 52 return s0 53 default: 54 return s0 + ";\t" + s1 55 } 56 } 57 58 func JoinStackText(s0 string, s1 StackTrace) string { 59 if s1 == nil { 60 return s0 61 } 62 return s0 + "\n" + stackTracePrintPrefix + s1.StackTraceAsText() 63 } 64 65 /*******************************************************************/ 66 67 type stackWrap struct { 68 st StackTrace 69 stDeepest StackTrace 70 stDeepMod DeepestStackMode 71 err error 72 } 73 74 func (v stackWrap) ShallowStackTrace() StackTrace { 75 return v.st 76 } 77 78 func (v stackWrap) DeepestStackTrace() (StackTrace, DeepestStackMode) { 79 if v.stDeepest == nil { 80 return v.st, v.stDeepMod 81 } 82 return v.stDeepest, v.stDeepMod 83 } 84 85 func (v stackWrap) Cause() error { 86 return v.Unwrap() 87 } 88 89 func (v stackWrap) Unwrap() error { 90 return v.err 91 } 92 93 func (v stackWrap) LogString() string { 94 if vv, ok := v.err.(logStringer); ok { 95 return vv.LogString() 96 } 97 return v.err.Error() 98 } 99 100 func (v stackWrap) Error() string { 101 return v.LogString() 102 } 103 104 /*******************************************************************/ 105 106 type panicWrap struct { 107 st StackTrace 108 recovered interface{} 109 stDeepest StackTrace 110 fmtWrap 111 stDeepMod DeepestStackMode 112 } 113 114 func (v panicWrap) Cause() error { 115 if err := v.Unwrap(); err != nil { 116 return err 117 } 118 return errors.New(v.LogString()) 119 } 120 121 func (v panicWrap) ShallowStackTrace() StackTrace { 122 return v.st 123 } 124 125 func (v panicWrap) DeepestStackTrace() (StackTrace, DeepestStackMode) { 126 if v.stDeepest == nil { 127 return v.st, v.stDeepMod 128 } 129 return v.stDeepest, v.stDeepMod 130 } 131 132 func (v panicWrap) Recovered() interface{} { 133 if v.recovered != nil { 134 return v.recovered 135 } 136 return v.fmtWrap 137 } 138 139 func (v panicWrap) Unwrap() error { 140 if err, ok := v.recovered.(error); ok { 141 return err 142 } 143 return nil 144 } 145 146 func (v panicWrap) Error() string { 147 return v.LogString() 148 } 149 150 /*******************************************************************/ 151 152 type fmtWrap struct { 153 msg string 154 extra interface{} 155 severity Severity 156 useExtra bool // indicates that extra part is included into msg 157 } 158 159 func (v fmtWrap) extraString() string { 160 if !v.useExtra { 161 return "" 162 } 163 if vv, ok := v.extra.(logStringer); ok { 164 return vv.LogString() 165 } 166 return defaultFmt(v.extra, false) 167 } 168 169 func (v fmtWrap) LogString() string { 170 return joinErrString(v.msg, v.extraString()) 171 } 172 173 func (v fmtWrap) Error() string { 174 return v.LogString() 175 } 176 177 func (v fmtWrap) ExtraInfo() (string, Severity, interface{}) { 178 if !v.useExtra { 179 return "", v.severity, v.extra 180 } 181 return v.msg, v.severity, v.extra 182 } 183 184 func (v fmtWrap) AsDetail(target interface{}) bool { 185 return asDetail(v.extra, target) 186 } 187 188 /*******************************************************************/ 189 190 type detailsWrap struct { 191 err error 192 details fmtWrap 193 isComparable bool 194 } 195 196 func (v detailsWrap) Unwrap() error { 197 return v.err 198 } 199 200 func (v detailsWrap) LogString() string { 201 s := "" 202 if vv, ok := v.err.(logStringer); ok { 203 s = vv.LogString() 204 } else { 205 s = v.err.Error() 206 } 207 208 return joinErrString(v.details.LogString(), s) 209 } 210 211 func (v detailsWrap) Is(target error) bool { 212 if e, ok := v.details.extra.(error); ok { 213 return isThis(v.isComparable, e, target) 214 } 215 return false 216 } 217 218 func (v detailsWrap) As(target interface{}) bool { 219 if e, ok := v.details.extra.(error); ok { 220 fnAs := errors.As // to avoid GoLang warning on use of errors.As 221 return fnAs(e, target) 222 } 223 return false 224 } 225 226 func (v detailsWrap) AsDetail(target interface{}) bool { 227 return v.details.AsDetail(target) 228 } 229 230 func (v detailsWrap) Error() string { 231 return joinErrString(v.details.LogString(), v.err.Error()) 232 } 233 234 func (v detailsWrap) ExtraInfo() (string, Severity, interface{}) { 235 return v.details.ExtraInfo() 236 } 237 238 /*******************************************************************/ 239 240 type severityWrap struct { 241 err error 242 severity Severity 243 } 244 245 func (v severityWrap) Unwrap() error { 246 return v.err 247 } 248 249 func (v severityWrap) LogString() string { 250 if vv, ok := v.err.(logStringer); ok { 251 return vv.LogString() 252 } 253 return v.err.Error() 254 } 255 256 func (v severityWrap) Error() string { 257 return v.err.Error() 258 } 259 260 func (v severityWrap) ExtraInfo() (string, Severity, interface{}) { 261 return "", v.severity, nil 262 }