github.com/ydb-platform/ydb-go-sdk/v3@v3.57.0/internal/xerrors/stacktrace.go (about) 1 package xerrors 2 3 import ( 4 grpcStatus "google.golang.org/grpc/status" 5 6 "github.com/ydb-platform/ydb-go-sdk/v3/internal/stack" 7 ) 8 9 type withStackTraceOptions struct { 10 skipDepth int 11 } 12 13 type withStackTraceOption func(o *withStackTraceOptions) 14 15 func WithSkipDepth(skipDepth int) withStackTraceOption { 16 return func(o *withStackTraceOptions) { 17 o.skipDepth = skipDepth 18 } 19 } 20 21 // WithStackTrace is a wrapper over original err with file:line identification 22 func WithStackTrace(err error, opts ...withStackTraceOption) error { 23 if err == nil { 24 return nil 25 } 26 options := withStackTraceOptions{} 27 for _, o := range opts { 28 if o != nil { 29 o(&options) 30 } 31 } 32 if s, has := grpcStatus.FromError(err); has { 33 return &stackTransportError{ 34 stackError: stackError{ 35 stackRecord: stack.Record(options.skipDepth + 1), 36 err: err, 37 }, 38 status: s, 39 } 40 } 41 42 return &stackError{ 43 stackRecord: stack.Record(options.skipDepth + 1), 44 err: err, 45 } 46 } 47 48 type stackError struct { 49 stackRecord string 50 err error 51 } 52 53 func (e *stackError) Error() string { 54 return e.err.Error() + " at `" + e.stackRecord + "`" 55 } 56 57 func (e *stackError) Unwrap() error { 58 return e.err 59 } 60 61 type stackTransportError struct { 62 stackError 63 status *grpcStatus.Status 64 } 65 66 func (e *stackTransportError) GRPCStatus() *grpcStatus.Status { 67 return e.status 68 }