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

     1  // Copyright 2012-2021 The NATS Authors
     2  // Licensed under the Apache License, Version 2.0 (the "License");
     3  // you may not use this file except in compliance with the License.
     4  // You may obtain a copy of the License at
     5  //
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package server
    15  
    16  import (
    17  	"errors"
    18  	"fmt"
    19  )
    20  
    21  var (
    22  	// ErrConnectionClosed represents an error condition on a closed connection.
    23  	ErrConnectionClosed = errors.New("connection closed")
    24  
    25  	// ErrAuthentication represents an error condition on failed authentication.
    26  	ErrAuthentication = errors.New("authentication error")
    27  
    28  	// ErrAuthTimeout represents an error condition on failed authorization due to timeout.
    29  	ErrAuthTimeout = errors.New("authentication timeout")
    30  
    31  	// ErrAuthExpired represents an expired authorization due to timeout.
    32  	ErrAuthExpired = errors.New("authentication expired")
    33  
    34  	// ErrMaxPayload represents an error condition when the payload is too big.
    35  	ErrMaxPayload = errors.New("maximum payload exceeded")
    36  
    37  	// ErrMaxControlLine represents an error condition when the control line is too big.
    38  	ErrMaxControlLine = errors.New("maximum control line exceeded")
    39  
    40  	// ErrReservedPublishSubject represents an error condition when sending to a reserved subject, e.g. _SYS.>
    41  	ErrReservedPublishSubject = errors.New("reserved internal subject")
    42  
    43  	// ErrBadPublishSubject represents an error condition for an invalid publish subject.
    44  	ErrBadPublishSubject = errors.New("invalid publish subject")
    45  
    46  	// ErrBadSubject represents an error condition for an invalid subject.
    47  	ErrBadSubject = errors.New("invalid subject")
    48  
    49  	// ErrBadQualifier is used to error on a bad qualifier for a transform.
    50  	ErrBadQualifier = errors.New("bad qualifier")
    51  
    52  	// ErrBadClientProtocol signals a client requested an invalid client protocol.
    53  	ErrBadClientProtocol = errors.New("invalid client protocol")
    54  
    55  	// ErrTooManyConnections signals a client that the maximum number of connections supported by the
    56  	// server has been reached.
    57  	ErrTooManyConnections = errors.New("maximum connections exceeded")
    58  
    59  	// ErrTooManyAccountConnections signals that an account has reached its maximum number of active
    60  	// connections.
    61  	ErrTooManyAccountConnections = errors.New("maximum account active connections exceeded")
    62  
    63  	// ErrLeafNodeLoop signals a leafnode is trying to register for a cluster we already have registered.
    64  	ErrLeafNodeLoop = errors.New("leafnode loop detected")
    65  
    66  	// ErrTooManySubs signals a client that the maximum number of subscriptions per connection
    67  	// has been reached.
    68  	ErrTooManySubs = errors.New("maximum subscriptions exceeded")
    69  
    70  	// ErrTooManySubTokens signals a client that the subject has too many tokens.
    71  	ErrTooManySubTokens = errors.New("subject has exceeded number of tokens limit")
    72  
    73  	// ErrClientConnectedToRoutePort represents an error condition when a client
    74  	// attempted to connect to the route listen port.
    75  	ErrClientConnectedToRoutePort = errors.New("attempted to connect to route port")
    76  
    77  	// ErrClientConnectedToLeafNodePort represents an error condition when a client
    78  	// attempted to connect to the leaf node listen port.
    79  	ErrClientConnectedToLeafNodePort = errors.New("attempted to connect to leaf node port")
    80  
    81  	// ErrLeafNodeHasSameClusterName represents an error condition when a leafnode is a cluster
    82  	// and it has the same cluster name as the hub cluster.
    83  	ErrLeafNodeHasSameClusterName = errors.New("remote leafnode has same cluster name")
    84  
    85  	// ErrLeafNodeDisabled is when we disable leafnodes.
    86  	ErrLeafNodeDisabled = errors.New("leafnodes disabled")
    87  
    88  	// ErrConnectedToWrongPort represents an error condition when a connection is attempted
    89  	// to the wrong listen port (for instance a LeafNode to a client port, etc...)
    90  	ErrConnectedToWrongPort = errors.New("attempted to connect to wrong port")
    91  
    92  	// ErrAccountExists is returned when an account is attempted to be registered
    93  	// but already exists.
    94  	ErrAccountExists = errors.New("account exists")
    95  
    96  	// ErrBadAccount represents a malformed or incorrect account.
    97  	ErrBadAccount = errors.New("bad account")
    98  
    99  	// ErrReservedAccount represents a reserved account that can not be created.
   100  	ErrReservedAccount = errors.New("reserved account")
   101  
   102  	// ErrMissingAccount is returned when an account does not exist.
   103  	ErrMissingAccount = errors.New("account missing")
   104  
   105  	// ErrMissingService is returned when an account does not have an exported service.
   106  	ErrMissingService = errors.New("service missing")
   107  
   108  	// ErrBadServiceType is returned when latency tracking is being applied to non-singleton response types.
   109  	ErrBadServiceType = errors.New("bad service response type")
   110  
   111  	// ErrBadSampling is returned when the sampling for latency tracking is not 1 >= sample <= 100.
   112  	ErrBadSampling = errors.New("bad sampling percentage, should be 1-100")
   113  
   114  	// ErrAccountValidation is returned when an account has failed validation.
   115  	ErrAccountValidation = errors.New("account validation failed")
   116  
   117  	// ErrAccountExpired is returned when an account has expired.
   118  	ErrAccountExpired = errors.New("account expired")
   119  
   120  	// ErrNoAccountResolver is returned when we attempt an update but do not have an account resolver.
   121  	ErrNoAccountResolver = errors.New("account resolver missing")
   122  
   123  	// ErrAccountResolverUpdateTooSoon is returned when we attempt an update too soon to last request.
   124  	ErrAccountResolverUpdateTooSoon = errors.New("account resolver update too soon")
   125  
   126  	// ErrAccountResolverSameClaims is returned when same claims have been fetched.
   127  	ErrAccountResolverSameClaims = errors.New("account resolver no new claims")
   128  
   129  	// ErrStreamImportAuthorization is returned when a stream import is not authorized.
   130  	ErrStreamImportAuthorization = errors.New("stream import not authorized")
   131  
   132  	// ErrStreamImportBadPrefix is returned when a stream import prefix contains wildcards.
   133  	ErrStreamImportBadPrefix = errors.New("stream import prefix can not contain wildcard tokens")
   134  
   135  	// ErrStreamImportDuplicate is returned when a stream import is a duplicate of one that already exists.
   136  	ErrStreamImportDuplicate = errors.New("stream import already exists")
   137  
   138  	// ErrServiceImportAuthorization is returned when a service import is not authorized.
   139  	ErrServiceImportAuthorization = errors.New("service import not authorized")
   140  
   141  	// ErrImportFormsCycle is returned when an import would form a cycle.
   142  	ErrImportFormsCycle = errors.New("import forms a cycle")
   143  
   144  	// ErrCycleSearchDepth is returned when we have exceeded our maximum search depth..
   145  	ErrCycleSearchDepth = errors.New("search cycle depth exhausted")
   146  
   147  	// ErrClientOrRouteConnectedToGatewayPort represents an error condition when
   148  	// a client or route attempted to connect to the Gateway port.
   149  	ErrClientOrRouteConnectedToGatewayPort = errors.New("attempted to connect to gateway port")
   150  
   151  	// ErrWrongGateway represents an error condition when a server receives a connect
   152  	// request from a remote Gateway with a destination name that does not match the server's
   153  	// Gateway's name.
   154  	ErrWrongGateway = errors.New("wrong gateway")
   155  
   156  	// ErrNoSysAccount is returned when an attempt to publish or subscribe is made
   157  	// when there is no internal system account defined.
   158  	ErrNoSysAccount = errors.New("system account not setup")
   159  
   160  	// ErrRevocation is returned when a credential has been revoked.
   161  	ErrRevocation = errors.New("credentials have been revoked")
   162  
   163  	// ErrServerNotRunning is used to signal an error that a server is not running.
   164  	ErrServerNotRunning = errors.New("server is not running")
   165  
   166  	// ErrBadMsgHeader signals the parser detected a bad message header
   167  	ErrBadMsgHeader = errors.New("bad message header detected")
   168  
   169  	// ErrMsgHeadersNotSupported signals the parser detected a message header
   170  	// but they are not supported on this server.
   171  	ErrMsgHeadersNotSupported = errors.New("message headers not supported")
   172  
   173  	// ErrNoRespondersRequiresHeaders signals that a client needs to have headers
   174  	// on if they want no responders behavior.
   175  	ErrNoRespondersRequiresHeaders = errors.New("no responders requires headers support")
   176  
   177  	// ErrClusterNameConfigConflict signals that the options for cluster name in cluster and gateway are in conflict.
   178  	ErrClusterNameConfigConflict = errors.New("cluster name conflicts between cluster and gateway definitions")
   179  
   180  	// ErrClusterNameRemoteConflict signals that a remote server has a different cluster name.
   181  	ErrClusterNameRemoteConflict = errors.New("cluster name from remote server conflicts")
   182  
   183  	// ErrMalformedSubject is returned when a subscription is made with a subject that does not conform to subject rules.
   184  	ErrMalformedSubject = errors.New("malformed subject")
   185  
   186  	// ErrSubscribePermissionViolation is returned when processing of a subscription fails due to permissions.
   187  	ErrSubscribePermissionViolation = errors.New("subscribe permission violation")
   188  
   189  	// ErrNoTransforms signals no subject transforms are available to map this subject.
   190  	ErrNoTransforms = errors.New("no matching transforms available")
   191  
   192  	// ErrCertNotPinned is returned when pinned certs are set and the certificate is not in it
   193  	ErrCertNotPinned = errors.New("certificate not pinned")
   194  
   195  	// ErrDuplicateServerName is returned when processing a server remote connection and
   196  	// the server reports that this server name is already used in the cluster.
   197  	ErrDuplicateServerName = errors.New("duplicate server name")
   198  
   199  	// ErrMinimumVersionRequired is returned when a connection is not at the minimum version required.
   200  	ErrMinimumVersionRequired = errors.New("minimum version required")
   201  
   202  	// ErrInvalidMappingDestination is used for all subject mapping destination errors
   203  	ErrInvalidMappingDestination = errors.New("invalid mapping destination")
   204  
   205  	// ErrInvalidMappingDestinationSubject is used to error on a bad transform destination mapping
   206  	ErrInvalidMappingDestinationSubject = fmt.Errorf("%w: invalid subject", ErrInvalidMappingDestination)
   207  
   208  	// ErrMappingDestinationNotUsingAllWildcards is used to error on a transform destination not using all of the token wildcards
   209  	ErrMappingDestinationNotUsingAllWildcards = fmt.Errorf("%w: not using all of the token wildcard(s)", ErrInvalidMappingDestination)
   210  
   211  	// ErrUnknownMappingDestinationFunction is returned when a subject mapping destination contains an unknown mustache-escaped mapping function.
   212  	ErrUnknownMappingDestinationFunction = fmt.Errorf("%w: unknown function", ErrInvalidMappingDestination)
   213  
   214  	// ErrMappingDestinationIndexOutOfRange is returned when the mapping destination function is passed an out of range wildcard index value for one of it's arguments
   215  	ErrMappingDestinationIndexOutOfRange = fmt.Errorf("%w: wildcard index out of range", ErrInvalidMappingDestination)
   216  
   217  	// ErrMappingDestinationNotEnoughArgs is returned when the mapping destination function is not passed enough arguments
   218  	ErrMappingDestinationNotEnoughArgs = fmt.Errorf("%w: not enough arguments passed to the function", ErrInvalidMappingDestination)
   219  
   220  	// ErrMappingDestinationInvalidArg is returned when the mapping destination function is passed and invalid argument
   221  	ErrMappingDestinationInvalidArg = fmt.Errorf("%w: function argument is invalid or in the wrong format", ErrInvalidMappingDestination)
   222  
   223  	// ErrMappingDestinationTooManyArgs is returned when the mapping destination function is passed too many arguments
   224  	ErrMappingDestinationTooManyArgs = fmt.Errorf("%w: too many arguments passed to the function", ErrInvalidMappingDestination)
   225  
   226  	// ErrMappingDestinationNotSupportedForImport is returned when you try to use a mapping function other than wildcard in a transform that needs to be reversible (i.e. an import)
   227  	ErrMappingDestinationNotSupportedForImport = fmt.Errorf("%w: the only mapping function allowed for import transforms is {{Wildcard()}}", ErrInvalidMappingDestination)
   228  )
   229  
   230  // mappingDestinationErr is a type of subject mapping destination error
   231  type mappingDestinationErr struct {
   232  	token string
   233  	err   error
   234  }
   235  
   236  func (e *mappingDestinationErr) Error() string {
   237  	return fmt.Sprintf("%s in %s", e.err, e.token)
   238  }
   239  
   240  func (e *mappingDestinationErr) Is(target error) bool {
   241  	return target == ErrInvalidMappingDestination
   242  }
   243  
   244  // configErr is a configuration error.
   245  type configErr struct {
   246  	token  token
   247  	reason string
   248  }
   249  
   250  // Source reports the location of a configuration error.
   251  func (e *configErr) Source() string {
   252  	return fmt.Sprintf("%s:%d:%d", e.token.SourceFile(), e.token.Line(), e.token.Position())
   253  }
   254  
   255  // Error reports the location and reason from a configuration error.
   256  func (e *configErr) Error() string {
   257  	if e.token != nil {
   258  		return fmt.Sprintf("%s: %s", e.Source(), e.reason)
   259  	}
   260  	return e.reason
   261  }
   262  
   263  // unknownConfigFieldErr is an error reported in pedantic mode.
   264  type unknownConfigFieldErr struct {
   265  	configErr
   266  	field string
   267  }
   268  
   269  // Error reports that an unknown field was in the configuration.
   270  func (e *unknownConfigFieldErr) Error() string {
   271  	return fmt.Sprintf("%s: unknown field %q", e.Source(), e.field)
   272  }
   273  
   274  // configWarningErr is an error reported in pedantic mode.
   275  type configWarningErr struct {
   276  	configErr
   277  	field string
   278  }
   279  
   280  // Error reports a configuration warning.
   281  func (e *configWarningErr) Error() string {
   282  	return fmt.Sprintf("%s: invalid use of field %q: %s", e.Source(), e.field, e.reason)
   283  }
   284  
   285  // processConfigErr is the result of processing the configuration from the server.
   286  type processConfigErr struct {
   287  	errors   []error
   288  	warnings []error
   289  }
   290  
   291  // Error returns the collection of errors separated by new lines,
   292  // warnings appear first then hard errors.
   293  func (e *processConfigErr) Error() string {
   294  	var msg string
   295  	for _, err := range e.Warnings() {
   296  		msg += err.Error() + "\n"
   297  	}
   298  	for _, err := range e.Errors() {
   299  		msg += err.Error() + "\n"
   300  	}
   301  	return msg
   302  }
   303  
   304  // Warnings returns the list of warnings.
   305  func (e *processConfigErr) Warnings() []error {
   306  	return e.warnings
   307  }
   308  
   309  // Errors returns the list of errors.
   310  func (e *processConfigErr) Errors() []error {
   311  	return e.errors
   312  }
   313  
   314  // errCtx wraps an error and stores additional ctx information for tracing.
   315  // Does not print or return it unless explicitly requested.
   316  type errCtx struct {
   317  	error
   318  	ctx string
   319  }
   320  
   321  func NewErrorCtx(err error, format string, args ...interface{}) error {
   322  	return &errCtx{err, fmt.Sprintf(format, args...)}
   323  }
   324  
   325  // Unwrap implement to work with errors.Is and errors.As
   326  func (e *errCtx) Unwrap() error {
   327  	if e == nil {
   328  		return nil
   329  	}
   330  	return e.error
   331  }
   332  
   333  // Context for error
   334  func (e *errCtx) Context() string {
   335  	if e == nil {
   336  		return ""
   337  	}
   338  	return e.ctx
   339  }
   340  
   341  // UnpackIfErrorCtx return Error or, if type is right error and context
   342  func UnpackIfErrorCtx(err error) string {
   343  	if e, ok := err.(*errCtx); ok {
   344  		if _, ok := e.error.(*errCtx); ok {
   345  			return fmt.Sprint(UnpackIfErrorCtx(e.error), ": ", e.Context())
   346  		}
   347  		return fmt.Sprint(e.Error(), ": ", e.Context())
   348  	}
   349  	return err.Error()
   350  }
   351  
   352  // implements: go 1.13 errors.Unwrap(err error) error
   353  // TODO replace with native code once we no longer support go1.12
   354  func errorsUnwrap(err error) error {
   355  	u, ok := err.(interface {
   356  		Unwrap() error
   357  	})
   358  	if !ok {
   359  		return nil
   360  	}
   361  	return u.Unwrap()
   362  }
   363  
   364  // ErrorIs implements: go 1.13 errors.Is(err, target error) bool
   365  // TODO replace with native code once we no longer support go1.12
   366  func ErrorIs(err, target error) bool {
   367  	// this is an outright copy of go 1.13 errors.Is(err, target error) bool
   368  	// removed isComparable
   369  	if err == nil || target == nil {
   370  		return err == target
   371  	}
   372  
   373  	for {
   374  		if err == target {
   375  			return true
   376  		}
   377  		if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) {
   378  			return true
   379  		}
   380  		// TODO: consider supporing target.Is(err). This would allow
   381  		// user-definable predicates, but also may allow for coping with sloppy
   382  		// APIs, thereby making it easier to get away with them.
   383  		if err = errorsUnwrap(err); err == nil {
   384  			return false
   385  		}
   386  	}
   387  }