get.pme.sh/pnats@v0.0.0-20240304004023-26bb5a137ed0/server/jetstream_errors.go (about)

     1  package server
     2  
     3  import (
     4  	"fmt"
     5  )
     6  
     7  type errOpts struct {
     8  	err error
     9  }
    10  
    11  // ErrorOption configures a NATS Error helper
    12  type ErrorOption func(*errOpts)
    13  
    14  // Unless ensures that if err is a ApiErr that err will be returned rather than the one being created via the helper
    15  func Unless(err error) ErrorOption {
    16  	return func(opts *errOpts) {
    17  		opts.err = err
    18  	}
    19  }
    20  
    21  func parseOpts(opts []ErrorOption) *errOpts {
    22  	eopts := &errOpts{}
    23  	for _, opt := range opts {
    24  		opt(eopts)
    25  	}
    26  	return eopts
    27  }
    28  
    29  type ErrorIdentifier uint16
    30  
    31  // IsNatsErr determines if an error matches ID, if multiple IDs are given if the error matches any of these the function will be true
    32  func IsNatsErr(err error, ids ...ErrorIdentifier) bool {
    33  	if err == nil {
    34  		return false
    35  	}
    36  
    37  	ce, ok := err.(*ApiError)
    38  	if !ok || ce == nil {
    39  		return false
    40  	}
    41  
    42  	for _, id := range ids {
    43  		ae, ok := ApiErrors[id]
    44  		if !ok || ae == nil {
    45  			continue
    46  		}
    47  
    48  		if ce.ErrCode == ae.ErrCode {
    49  			return true
    50  		}
    51  	}
    52  
    53  	return false
    54  }
    55  
    56  // ApiError is included in all responses if there was an error.
    57  type ApiError struct {
    58  	Code        int    `json:"code"`
    59  	ErrCode     uint16 `json:"err_code,omitempty"`
    60  	Description string `json:"description,omitempty"`
    61  }
    62  
    63  // ErrorsData is the source data for generated errors as found in errors.json
    64  type ErrorsData struct {
    65  	Constant    string `json:"constant"`
    66  	Code        int    `json:"code"`
    67  	ErrCode     uint16 `json:"error_code"`
    68  	Description string `json:"description"`
    69  	Comment     string `json:"comment"`
    70  	Help        string `json:"help"`
    71  	URL         string `json:"url"`
    72  	Deprecates  string `json:"deprecates"`
    73  }
    74  
    75  func (e *ApiError) Error() string {
    76  	return fmt.Sprintf("%s (%d)", e.Description, e.ErrCode)
    77  }
    78  
    79  func (e *ApiError) toReplacerArgs(replacements []interface{}) []string {
    80  	var (
    81  		ra  []string
    82  		key string
    83  	)
    84  
    85  	for i, replacement := range replacements {
    86  		if i%2 == 0 {
    87  			key = replacement.(string)
    88  			continue
    89  		}
    90  
    91  		switch v := replacement.(type) {
    92  		case string:
    93  			ra = append(ra, key, v)
    94  		case error:
    95  			ra = append(ra, key, v.Error())
    96  		default:
    97  			ra = append(ra, key, fmt.Sprintf("%v", v))
    98  		}
    99  	}
   100  
   101  	return ra
   102  }