github.com/ydb-platform/ydb-go-sdk/v3@v3.57.0/internal/xerrors/retryable.go (about)

     1  package xerrors
     2  
     3  import (
     4  	"errors"
     5  
     6  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/backoff"
     7  )
     8  
     9  type retryableError struct {
    10  	name              string
    11  	err               error
    12  	backoffType       backoff.Type
    13  	mustDeleteSession bool
    14  	code              int32
    15  }
    16  
    17  func (e *retryableError) Code() int32 {
    18  	return e.code
    19  }
    20  
    21  func (e *retryableError) Name() string {
    22  	return "retryable/" + e.name
    23  }
    24  
    25  func (e *retryableError) Type() Type {
    26  	return TypeRetryable
    27  }
    28  
    29  func (e *retryableError) BackoffType() backoff.Type {
    30  	return e.backoffType
    31  }
    32  
    33  func (e *retryableError) MustDeleteSession() bool {
    34  	return e.mustDeleteSession
    35  }
    36  
    37  func (e *retryableError) Error() string {
    38  	return e.err.Error()
    39  }
    40  
    41  func (e *retryableError) Unwrap() error {
    42  	return e.err
    43  }
    44  
    45  type RetryableErrorOption func(e *retryableError)
    46  
    47  func WithBackoff(t backoff.Type) RetryableErrorOption {
    48  	return func(e *retryableError) {
    49  		e.backoffType = t
    50  	}
    51  }
    52  
    53  func WithName(name string) RetryableErrorOption {
    54  	return func(e *retryableError) {
    55  		e.name = name
    56  	}
    57  }
    58  
    59  func WithDeleteSession() RetryableErrorOption {
    60  	return func(e *retryableError) {
    61  		e.mustDeleteSession = true
    62  	}
    63  }
    64  
    65  func Retryable(err error, opts ...RetryableErrorOption) error {
    66  	var (
    67  		e  Error
    68  		re = &retryableError{
    69  			err:  err,
    70  			name: "CUSTOM",
    71  			code: -1,
    72  		}
    73  	)
    74  	if As(err, &e) {
    75  		re.backoffType = e.BackoffType()
    76  		re.mustDeleteSession = e.MustDeleteSession()
    77  		re.code = e.Code()
    78  		re.name = e.Name()
    79  	}
    80  	for _, o := range opts {
    81  		if o != nil {
    82  			o(re)
    83  		}
    84  	}
    85  
    86  	return re
    87  }
    88  
    89  // RetryableError return Error if err is retriable error, else nil
    90  func RetryableError(err error) Error {
    91  	var e *retryableError
    92  	if errors.As(err, &e) {
    93  		return e
    94  	}
    95  
    96  	return nil
    97  }