nats.go icon indicating copy to clipboard operation
nats.go copied to clipboard

KV update error is not a type

Open andreib1 opened this issue 3 years ago • 3 comments

As a developer I would expect Key/Value Update to return a typed error on wrong last sequence So that I can retry the update.

Background The server returns:

  nats.apiError
    Code = {int} 400
    ErrorCode = {int} 10071
    Description = {string} "wrong last sequence: 31"

Which gets translated into the string error:

  "nats: wrong last sequence: 31"

Neither of which are natively machine readable, so the the message has to be substring checked to determine the cause.

andreib1 avatar May 31 '22 00:05 andreib1

The error code is unique to the error type, with code being more general.

derekcollison avatar May 31 '22 02:05 derekcollison

The server error codes are designed to solve this problem, undoubtedly nats.go Does not expose them to the user in a usable way.

Would exposing them 10071 do what you need?

ripienaar avatar May 31 '22 04:05 ripienaar

Yes, it would be perfect. I would advise exposing apiError as ApiError adding an Error() method with returns Error.Description. Then you could use @js.go:469

		return nil, fmt.Errorf("nats: %w", pa.Error)

instead of

		return nil, fmt.Errorf("nats: %s", pa.Error.Description)

Which would return a neat wrapped error for any callers interested in getting at the underlying cause.

andreib1 avatar May 31 '22 08:05 andreib1

Hi @andreib1

In client v1.17.0 we did 2 things:

  1. Exposed apiError as nats.APIError
  2. Added a new type for all JetStream-related errors: nats.JetStreamError. It combines both server and client errors and for server errors it wraps APIError.

So you can get to the JetStream error code in 2 ways:

  1. By matching it against JetStreamError interface and checking for underlying APIError:
var errCode nats.ErrorCode
var jsErr nats.JetStreamError
if ok = errors.As(err, &jsErr); ok {
	if jsErr.APIError() != nil {
		errCode = jsErr.APIError().ErrorCode
	}
}
  1. By matching it against nats.APIError directly:
var errCode nats.ErrorCode
var apiErr *nats.APIError
if ok = errors.As(err, &apiErr); ok {
	errCode = apiErr.ErrorCode
}

piotrpio avatar Sep 19 '22 10:09 piotrpio