github.com/qioalice/ekago/v3@v3.3.2-0.20221202205325-5c262d586ee4/ekaunsafe/ekaerr.go (about) 1 // Copyright © 2020. All rights reserved. 2 // Author: Ilya Stroy. 3 // Contacts: iyuryevich@pm.me, https://github.com/qioalice 4 // License: https://opensource.org/licenses/MIT 5 6 package ekaunsafe 7 8 import ( 9 "unsafe" 10 11 "github.com/qioalice/ekago/v3/ekaerr" 12 "github.com/qioalice/ekago/v3/ekasys" 13 "github.com/qioalice/ekago/v3/internal/ekaletter" 14 ) 15 16 type ( 17 // CbErrorUpdateStacktrace is a special func alias that is an argument 18 // of ErrorUpdateStacktrace function. 19 CbErrorUpdateStacktrace func(oldStacktrace ekasys.StackTrace) (newStacktrace ekasys.StackTrace) 20 ) 21 22 // ErrorGetLetter returns an underlying ekaletter.Letter from provided ekaerr.Error object. 23 // Returns nil if err is not valid. 24 func ErrorGetLetter(err *ekaerr.Error) *ekaletter.Letter { 25 return ekaletter.BridgeErrorGetLetter(unsafe.Pointer(err)) 26 } 27 28 // ErrorUpdateStacktrace calls provided callback to change ekaerr.Error's stacktrace. 29 // Your callback must not be nil, error must be valid 30 // and your callback should return a new (modified) stacktrace that will be used. 31 func ErrorUpdateStacktrace(err *ekaerr.Error, cb CbErrorUpdateStacktrace) { 32 33 if cb == nil || err.IsNil() { 34 return 35 } 36 37 l := ErrorGetLetter(err) 38 oldStacktraceLen := int16(len(l.StackTrace)) 39 40 l.StackTrace = cb(l.StackTrace) 41 newStacktraceLen := int16(len(l.StackTrace)) 42 43 if newStacktraceLen >= oldStacktraceLen { 44 return 45 } 46 47 errStackIdx := ekaletter.BridgeErrorGetStackIdx(unsafe.Pointer(err)) 48 if errStackIdx < newStacktraceLen { 49 return 50 } 51 52 ekaletter.BridgeErrorSetStackIdx(unsafe.Pointer(err), newStacktraceLen-1) 53 }