mirror of
https://github.com/gogrlx/nats-server.git
synced 2026-04-02 03:38:42 -07:00
Previously we had a few confusing functions like NewT and similar that were quite fragile to use due to minimal validation and a panic in go stdlib string Replacer. Now we generate helper methods for every string, these are used to access errors, fill in templates and conditional returns of error type using the new Unless() option We now get compile time errors for some common mistakes and have better IDE helpers for arguments etc Signed-off-by: R.I.Pienaar <rip@devco.net>
103 lines
2.1 KiB
Go
103 lines
2.1 KiB
Go
package server
|
|
|
|
import (
|
|
"fmt"
|
|
)
|
|
|
|
type errOpts struct {
|
|
err error
|
|
}
|
|
|
|
// ErrorOption configures a NATS Error helper
|
|
type ErrorOption func(*errOpts)
|
|
|
|
// Unless ensures that if err is a ApiErr that err will be returned rather than the one being created via the helper
|
|
func Unless(err error) ErrorOption {
|
|
return func(opts *errOpts) {
|
|
opts.err = err
|
|
}
|
|
}
|
|
|
|
func parseOpts(opts []ErrorOption) *errOpts {
|
|
eopts := &errOpts{}
|
|
for _, opt := range opts {
|
|
opt(eopts)
|
|
}
|
|
return eopts
|
|
}
|
|
|
|
type ErrorIdentifier uint16
|
|
|
|
// IsNatsErr determines if a error matches ID, if multiple IDs are given if the error matches any of these the function will be true
|
|
func IsNatsErr(err error, ids ...ErrorIdentifier) bool {
|
|
if err == nil {
|
|
return false
|
|
}
|
|
|
|
ce, ok := err.(*ApiError)
|
|
if !ok || ce == nil {
|
|
return false
|
|
}
|
|
|
|
for _, id := range ids {
|
|
ae, ok := ApiErrors[id]
|
|
if !ok || ae == nil {
|
|
continue
|
|
}
|
|
|
|
if ce.ErrCode == ae.ErrCode {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
// ApiError is included in all responses if there was an error.
|
|
type ApiError struct {
|
|
Code int `json:"code"`
|
|
ErrCode uint16 `json:"err_code,omitempty"`
|
|
Description string `json:"description,omitempty"`
|
|
}
|
|
|
|
// ErrorsData is the source data for generated errors as found in errors.json
|
|
type ErrorsData struct {
|
|
Constant string `json:"constant"`
|
|
Code int `json:"code"`
|
|
ErrCode uint16 `json:"error_code"`
|
|
Description string `json:"description"`
|
|
Comment string `json:"comment"`
|
|
Help string `json:"help"`
|
|
URL string `json:"url"`
|
|
Deprecates string `json:"deprecates"`
|
|
}
|
|
|
|
func (e *ApiError) Error() string {
|
|
return fmt.Sprintf("%s (%d)", e.Description, e.ErrCode)
|
|
}
|
|
|
|
func (e *ApiError) toReplacerArgs(replacements []interface{}) []string {
|
|
var (
|
|
ra []string
|
|
key string
|
|
)
|
|
|
|
for i, replacement := range replacements {
|
|
if i%2 == 0 {
|
|
key = replacement.(string)
|
|
continue
|
|
}
|
|
|
|
switch v := replacement.(type) {
|
|
case string:
|
|
ra = append(ra, key, v)
|
|
case error:
|
|
ra = append(ra, key, v.Error())
|
|
default:
|
|
ra = append(ra, key, fmt.Sprintf("%v", v))
|
|
}
|
|
}
|
|
|
|
return ra
|
|
}
|