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  }