From a52a9ec753aea456bb1d5edb74b54f54b89059eb Mon Sep 17 00:00:00 2001 From: Sam Tavakoli Date: Fri, 2 Dec 2022 13:10:14 +0000 Subject: [PATCH 1/2] Provide a way to handle 409 Leadership Changed errors in client Without this change, it makes it hard for clients to handle consumer errors relating to leadership changes differently from any other error. Follows same approach as ErrConsumerDeleted. --- js.go | 5 +++++ jserrors.go | 3 +++ 2 files changed, 8 insertions(+) diff --git a/js.go b/js.go index 607204406..362d75117 100644 --- a/js.go +++ b/js.go @@ -2580,6 +2580,11 @@ func checkMsg(msg *Msg, checkSts, isNoWait bool) (usrMsg bool, err error) { err = ErrConsumerDeleted break } + + if strings.Contains(strings.ToLower(string(msg.Header.Get(descrHdr))), "leadership change") { + err = ErrConsumerLeadershipChanged + break + } fallthrough default: err = fmt.Errorf("nats: %s", msg.Header.Get(descrHdr)) diff --git a/jserrors.go b/jserrors.go index 8b97e86ce..1d5031dbe 100644 --- a/jserrors.go +++ b/jserrors.go @@ -101,6 +101,9 @@ var ( // ErrConsumerDeleted is returned when attempting to send pull request to a consumer which does not exist ErrConsumerDeleted JetStreamError = &jsError{message: "consumer deleted"} + // ErrConsumerLeadershipChanged is returned when pending requests are no longer valid after leadership has changed + ErrConsumerLeadershipChanged JetStreamError = &jsError{message: "leadership changed"} + // DEPRECATED: ErrInvalidDurableName is no longer returned and will be removed in future releases. // Use ErrInvalidConsumerName instead. ErrInvalidDurableName = errors.New("nats: invalid durable name") From b2ad744a01c2c015e8c9ba8024523f5c31aa1ec0 Mon Sep 17 00:00:00 2001 From: Sam Tavakoli Date: Fri, 2 Dec 2022 16:38:38 +0000 Subject: [PATCH 2/2] PR Review feedback PR Review feedback over [slack](https://form3.slack.com/archives/C02281GJCJF/p1669986912679049). Currently there are already users who are performing error string comparision for this use case. To avoid introducing a breaking change until there is a better way of handling these error messages, we will retain the error message for the newly introduced canonical error value. --- jserrors.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jserrors.go b/jserrors.go index 1d5031dbe..dd81cae77 100644 --- a/jserrors.go +++ b/jserrors.go @@ -102,7 +102,7 @@ var ( ErrConsumerDeleted JetStreamError = &jsError{message: "consumer deleted"} // ErrConsumerLeadershipChanged is returned when pending requests are no longer valid after leadership has changed - ErrConsumerLeadershipChanged JetStreamError = &jsError{message: "leadership changed"} + ErrConsumerLeadershipChanged JetStreamError = &jsError{message: "Leadership Changed"} // DEPRECATED: ErrInvalidDurableName is no longer returned and will be removed in future releases. // Use ErrInvalidConsumerName instead.