init
Some checks failed
ci / macos (push) Has been cancelled
ci / ios (push) Has been cancelled
ci / check-linter (push) Has been cancelled

This commit is contained in:
wenzuhuai
2026-01-12 18:29:52 +08:00
commit d7bdb4f378
87 changed files with 12664 additions and 0 deletions

View File

@@ -0,0 +1,863 @@
// Copyright 2024 The NATS Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import Foundation
import Nats
public protocol JetStreamErrorProtocol: Error, CustomStringConvertible {}
public enum JetStreamError {
public struct APIError: Codable, Error {
public var code: UInt
public var errorCode: ErrorCode
public var description: String
enum CodingKeys: String, CodingKey {
case code = "code"
case errorCode = "err_code"
case description = "description"
}
}
public enum RequestError: JetStreamErrorProtocol {
case noResponders
case timeout
case emptyResponsePayload
case permissionDenied(String)
public var description: String {
switch self {
case .noResponders:
return "nats: no responders available for request"
case .timeout:
return "nats: request timed out"
case .emptyResponsePayload:
return "nats: empty response payload"
case .permissionDenied(let subject):
return "nats: permission denied on subject \(subject)"
}
}
}
public enum MessageMetadataError: JetStreamErrorProtocol {
case noReplyInMessage
case invalidPrefix
case invalidTokenNum
case invalidTokenValue
public var description: String {
switch self {
case .noReplyInMessage:
return "nats: did not fund reply subject in message"
case .invalidPrefix:
return "nats: invalid reply subject prefix"
case .invalidTokenNum:
return "nats: invalid token count"
case .invalidTokenValue:
return "nats: invalid token value"
}
}
}
public enum FetchError: JetStreamErrorProtocol {
case noHeartbeatReceived
case consumerDeleted
case badRequest
case noResponders
case consumerIsPush
case invalidResponse
case leadershipChanged
case unknownStatus(StatusCode, String?)
public var description: String {
switch self {
case .noHeartbeatReceived:
return "nats: no heartbeat received"
case .consumerDeleted:
return "nats: consumer deleted"
case .badRequest:
return "nats: bad request"
case .noResponders:
return "nats: no responders"
case .consumerIsPush:
return "nats: consumer is push based"
case .invalidResponse:
return "nats: no description in status response"
case .leadershipChanged:
return "nats: leadership changed"
case .unknownStatus(let status, let description):
if let description {
return "nats: unknown response status: \(status): \(description)"
} else {
return "nats: unknown response status: \(status)"
}
}
}
}
public enum AckError: JetStreamErrorProtocol {
case noReplyInMessage
public var description: String {
switch self {
case .noReplyInMessage:
return "nats: did not fund reply subject in message"
}
}
}
public enum StreamError: JetStreamErrorProtocol {
case nameRequired
case invalidStreamName(String)
case streamNotFound(APIError)
case streamNameExist(APIError)
case streamMessageExceedsMaximum(APIError)
case streamDelete(APIError)
case streamUpdate(APIError)
case streamInvalidExternalDeliverySubject(APIError)
case streamMirrorNotUpdatable(APIError)
case streamLimitsExceeded(APIError)
case invalidConfig(APIError)
case maximumStreamsLimit(APIError)
case streamSealed(APIError)
public var description: String {
switch self {
case .nameRequired:
return "nats: stream name is required"
case .invalidStreamName(let name):
return "nats: invalid stream name: \(name)"
case .streamNotFound(let err),
.streamNameExist(let err),
.streamMessageExceedsMaximum(let err),
.streamDelete(let err),
.streamUpdate(let err),
.streamInvalidExternalDeliverySubject(let err),
.streamMirrorNotUpdatable(let err),
.streamLimitsExceeded(let err),
.invalidConfig(let err),
.maximumStreamsLimit(let err),
.streamSealed(let err):
return "nats: \(err.description)"
}
}
internal init?(from err: APIError) {
switch err.errorCode {
case ErrorCode.streamNotFound:
self = .streamNotFound(err)
case ErrorCode.streamNameExist:
self = .streamNameExist(err)
case ErrorCode.streamMessageExceedsMaximum:
self = .streamMessageExceedsMaximum(err)
case ErrorCode.streamDelete:
self = .streamDelete(err)
case ErrorCode.streamUpdate:
self = .streamUpdate(err)
case ErrorCode.streamInvalidExternalDeliverySubject:
self = .streamInvalidExternalDeliverySubject(err)
case ErrorCode.streamMirrorNotUpdatable:
self = .streamMirrorNotUpdatable(err)
case ErrorCode.streamLimits:
self = .streamLimitsExceeded(err)
case ErrorCode.mirrorWithSources,
ErrorCode.streamSubjectOverlap,
ErrorCode.streamExternalDeletePrefixOverlaps,
ErrorCode.mirrorMaxMessageSizeTooBig,
ErrorCode.sourceMaxMessageSizeTooBig,
ErrorCode.streamInvalidConfig,
ErrorCode.mirrorWithSubjects,
ErrorCode.streamExternalApiOverlap,
ErrorCode.mirrorWithStartSequenceAndTime,
ErrorCode.mirrorWithSubjectFilters,
ErrorCode.streamReplicasNotSupported,
ErrorCode.streamReplicasNotUpdatable,
ErrorCode.streamMaxBytesRequired,
ErrorCode.streamMaxStreamBytesExceeded,
ErrorCode.streamNameContainsPathSeparators,
ErrorCode.replicasCountCannotBeNegative,
ErrorCode.sourceDuplicateDetected,
ErrorCode.sourceInvalidStreamName,
ErrorCode.mirrorInvalidStreamName,
ErrorCode.sourceMultipleFiltersNotAllowed,
ErrorCode.sourceInvalidSubjectFilter,
ErrorCode.sourceInvalidTransformDestination,
ErrorCode.sourceOverlappingSubjectFilters,
ErrorCode.streamExternalDeletePrefixOverlaps:
self = .invalidConfig(err)
case ErrorCode.maximumStreamsLimit:
self = .maximumStreamsLimit(err)
case ErrorCode.streamSealed:
self = .streamSealed(err)
default:
return nil
}
}
}
public enum PublishError: JetStreamErrorProtocol {
case streamWrongLastSequence(APIError)
case streamWrongLastMessageId(APIError)
case streamNotMatch(APIError)
case streamNotFound
public var description: String {
switch self {
case .streamWrongLastSequence(let err),
.streamWrongLastMessageId(let err),
.streamNotMatch(let err):
return "nats: \(err.description)"
case .streamNotFound:
return "nats: stream not found"
}
}
internal init?(from err: APIError) {
switch err.errorCode {
case ErrorCode.streamWrongLastSequence:
self = .streamWrongLastSequence(err)
case ErrorCode.streamWrongLastMessageId:
self = .streamWrongLastMessageId(err)
case ErrorCode.streamNotMatch:
self = .streamNotMatch(err)
default:
return nil
}
}
}
public enum ConsumerError: JetStreamErrorProtocol {
case consumerNotFound(APIError)
case maximumConsumersLimit(APIError)
case consumerNameExist(APIError)
case consumerDoesNotExist(APIError)
case invalidConfig(APIError)
public var description: String {
switch self {
case .consumerNotFound(let err),
.maximumConsumersLimit(let err),
.consumerNameExist(let err),
.consumerDoesNotExist(let err),
.invalidConfig(let err):
return "nats: \(err.description)"
}
}
internal init?(from err: APIError) {
switch err.errorCode {
case ErrorCode.consumerNotFound:
self = .consumerNotFound(err)
case ErrorCode.maximumConsumersLimit:
self = .maximumConsumersLimit(err)
case ErrorCode.consumerNameExist,
ErrorCode.consumerExistingActive,
ErrorCode.consumerAlreadyExists:
self = .consumerNameExist(err)
case ErrorCode.consumerDoesNotExist:
self = .consumerDoesNotExist(err)
case ErrorCode.consumerDeliverToWildcards,
ErrorCode.consumerPushMaxWaiting,
ErrorCode.consumerDeliverCycle,
ErrorCode.consumerMaxPendingAckPolicyRequired,
ErrorCode.consumerSmallHeartbeat,
ErrorCode.consumerPullRequiresAck,
ErrorCode.consumerPullNotDurable,
ErrorCode.consumerPullWithRateLimit,
ErrorCode.consumerPullNotDurable,
ErrorCode.consumerMaxWaitingNegative,
ErrorCode.consumerHeartbeatRequiresPush,
ErrorCode.consumerFlowControlRequiresPush,
ErrorCode.consumerDirectRequiresPush,
ErrorCode.consumerDirectRequiresEphemeral,
ErrorCode.consumerOnMapped,
ErrorCode.consumerFilterNotSubset,
ErrorCode.consumerInvalidPolicy,
ErrorCode.consumerInvalidSampling,
ErrorCode.consumerWithFlowControlNeedsHeartbeats,
ErrorCode.consumerWqRequiresExplicitAck,
ErrorCode.consumerWqMultipleUnfiltered,
ErrorCode.consumerWqConsumerNotUnique,
ErrorCode.consumerWqConsumerNotDeliverAll,
ErrorCode.consumerNameTooLong,
ErrorCode.consumerBadDurableName,
ErrorCode.consumerDescriptionTooLong,
ErrorCode.consumerInvalidDeliverSubject,
ErrorCode.consumerMaxRequestBatchNegative,
ErrorCode.consumerMaxRequestExpiresToSmall,
ErrorCode.consumerMaxDeliverBackoff,
ErrorCode.consumerMaxPendingAckExcess,
ErrorCode.consumerMaxRequestBatchExceeded,
ErrorCode.consumerReplicasExceedsStream,
ErrorCode.consumerNameContainsPathSeparators,
ErrorCode.consumerCreateFilterSubjectMismatch,
ErrorCode.consumerCreateDurableAndNameMismatch,
ErrorCode.replicasCountCannotBeNegative,
ErrorCode.consumerReplicasShouldMatchStream,
ErrorCode.consumerMetadataLength,
ErrorCode.consumerDuplicateFilterSubjects,
ErrorCode.consumerMultipleFiltersNotAllowed,
ErrorCode.consumerOverlappingSubjectFilters,
ErrorCode.consumerEmptyFilter,
ErrorCode.mirrorMultipleFiltersNotAllowed,
ErrorCode.mirrorInvalidSubjectFilter,
ErrorCode.mirrorOverlappingSubjectFilters,
ErrorCode.consumerInactiveThresholdExcess:
self = .invalidConfig(err)
default:
return nil
}
}
}
public enum StreamMessageError: JetStreamErrorProtocol {
case deleteSequenceNotFound(APIError)
public var description: String {
switch self {
case .deleteSequenceNotFound(let err):
return "nats: \(err.description)"
}
}
internal init?(from err: APIError) {
switch err.errorCode {
case ErrorCode.sequenceNotFound:
self = .deleteSequenceNotFound(err)
default:
return nil
}
}
}
public enum DirectGetError: JetStreamErrorProtocol {
case invalidResponse(String)
case errorResponse(StatusCode, String?)
public var description: String {
switch self {
case .invalidResponse(let cause):
return "invalid response: \(cause)"
case .errorResponse(let code, let description):
if let description {
return "unable to get message: \(code) \(description)"
} else {
return "unable to get message: \(code)"
}
}
}
}
}
public struct ErrorCode: Codable, Equatable {
public let rawValue: UInt64
/// Peer not a member
public static let clusterPeerNotMember = ErrorCode(rawValue: 10040)
/// Consumer expected to be ephemeral but detected a durable name set in subject
public static let consumerEphemeralWithDurable = ErrorCode(rawValue: 10019)
/// Stream external delivery prefix overlaps with stream subject
public static let streamExternalDeletePrefixOverlaps = ErrorCode(rawValue: 10022)
/// Resource limits exceeded for account
public static let accountResourcesExceeded = ErrorCode(rawValue: 10002)
/// Jetstream system temporarily unavailable
public static let clusterNotAvailable = ErrorCode(rawValue: 10008)
/// Subjects overlap with an existing stream
public static let streamSubjectOverlap = ErrorCode(rawValue: 10065)
/// Wrong last sequence
public static let streamWrongLastSequence = ErrorCode(rawValue: 10071)
/// Template name in subject does not match request
public static let nameNotMatchSubject = ErrorCode(rawValue: 10073)
/// No suitable peers for placement
public static let clusterNoPeers = ErrorCode(rawValue: 10005)
/// Consumer expected to be ephemeral but a durable name was set in request
public static let consumerEphemeralWithDurableName = ErrorCode(rawValue: 10020)
/// Insufficient resources
public static let insufficientResources = ErrorCode(rawValue: 10023)
/// Stream mirror must have max message size >= source
public static let mirrorMaxMessageSizeTooBig = ErrorCode(rawValue: 10030)
/// Generic error from stream deletion operation
public static let streamTemplateDeleteFailed = ErrorCode(rawValue: 10067)
/// Bad request
public static let badRequest = ErrorCode(rawValue: 10003)
/// Not currently supported in clustered mode
public static let notSupportedInClusterMode = ErrorCode(rawValue: 10036)
/// Consumer not found
public static let consumerNotFound = ErrorCode(rawValue: 10014)
/// Stream source must have max message size >= target
public static let sourceMaxMessageSizeTooBig = ErrorCode(rawValue: 10046)
/// Generic error when stream operation fails.
public static let streamAssignment = ErrorCode(rawValue: 10048)
/// Message size exceeds maximum allowed
public static let streamMessageExceedsMaximum = ErrorCode(rawValue: 10054)
/// Generic error for stream creation error with a string
public static let streamCreateTemplate = ErrorCode(rawValue: 10066)
/// Invalid JSON
public static let invalidJson = ErrorCode(rawValue: 10025)
/// Stream external delivery prefix must not contain wildcards
public static let streamInvalidExternalDeliverySubject = ErrorCode(rawValue: 10024)
/// Restore failed
public static let streamRestore = ErrorCode(rawValue: 10062)
/// Incomplete results
public static let clusterIncomplete = ErrorCode(rawValue: 10004)
/// Account not found
public static let noAccount = ErrorCode(rawValue: 10035)
/// General RAFT error
public static let raftGeneral = ErrorCode(rawValue: 10041)
/// Jetstream unable to subscribe to restore snapshot
public static let restoreSubscribeFailed = ErrorCode(rawValue: 10042)
/// Stream deletion failed
public static let streamDelete = ErrorCode(rawValue: 10050)
/// Stream external api prefix must not overlap
public static let streamExternalApiOverlap = ErrorCode(rawValue: 10021)
/// Stream mirrors can not contain subjects
public static let mirrorWithSubjects = ErrorCode(rawValue: 10034)
/// Jetstream not enabled
public static let jetstreamNotEnabled = ErrorCode(rawValue: 10076)
/// Jetstream not enabled for account
public static let jetstreamNotEnabledForAccount = ErrorCode(rawValue: 10039)
/// Sequence not found
public static let sequenceNotFound = ErrorCode(rawValue: 10043)
/// Stream mirror configuration can not be updated
public static let streamMirrorNotUpdatable = ErrorCode(rawValue: 10055)
/// Expected stream sequence does not match
public static let streamSequenceNotMatch = ErrorCode(rawValue: 10063)
/// Wrong last msg id
public static let streamWrongLastMessageId = ErrorCode(rawValue: 10070)
/// Jetstream unable to open temp storage for restore
public static let tempStorageFailed = ErrorCode(rawValue: 10072)
/// Insufficient storage resources available
public static let storageResourcesExceeded = ErrorCode(rawValue: 10047)
/// Stream name in subject does not match request
public static let streamMismatch = ErrorCode(rawValue: 10056)
/// Expected stream does not match
public static let streamNotMatch = ErrorCode(rawValue: 10060)
/// Setting up consumer mirror failed
public static let mirrorConsumerSetupFailed = ErrorCode(rawValue: 10029)
/// Expected an empty request payload
public static let notEmptyRequest = ErrorCode(rawValue: 10038)
/// Stream name already in use with a different configuration
public static let streamNameExist = ErrorCode(rawValue: 10058)
/// Tags placement not supported for operation
public static let clusterTags = ErrorCode(rawValue: 10011)
/// Maximum consumers limit reached
public static let maximumConsumersLimit = ErrorCode(rawValue: 10026)
/// General source consumer setup failure
public static let sourceConsumerSetupFailed = ErrorCode(rawValue: 10045)
/// Consumer creation failed
public static let consumerCreate = ErrorCode(rawValue: 10012)
/// Consumer expected to be durable but no durable name set in subject
public static let consumerDurableNameNotInSubject = ErrorCode(rawValue: 10016)
/// Stream limits error
public static let streamLimits = ErrorCode(rawValue: 10053)
/// Replicas configuration can not be updated
public static let streamReplicasNotUpdatable = ErrorCode(rawValue: 10061)
/// Template not found
public static let streamTemplateNotFound = ErrorCode(rawValue: 10068)
/// Jetstream cluster not assigned to this server
public static let clusterNotAssigned = ErrorCode(rawValue: 10007)
/// Jetstream cluster can't handle request
public static let clusterNotLeader = ErrorCode(rawValue: 10009)
/// Consumer name already in use
public static let consumerNameExist = ErrorCode(rawValue: 10013)
/// Stream mirrors can't also contain other sources
public static let mirrorWithSources = ErrorCode(rawValue: 10031)
/// Stream not found
public static let streamNotFound = ErrorCode(rawValue: 10059)
/// Jetstream clustering support required
public static let clusterRequired = ErrorCode(rawValue: 10010)
/// Consumer expected to be durable but a durable name was not set
public static let consumerDurableNameNotSet = ErrorCode(rawValue: 10018)
/// Maximum number of streams reached
public static let maximumStreamsLimit = ErrorCode(rawValue: 10027)
/// Stream mirrors can not have both start seq and start time configured
public static let mirrorWithStartSequenceAndTime = ErrorCode(rawValue: 10032)
/// Stream snapshot failed
public static let streamSnapshot = ErrorCode(rawValue: 10064)
/// Stream update failed
public static let streamUpdate = ErrorCode(rawValue: 10069)
/// Jetstream not in clustered mode
public static let clusterNotActive = ErrorCode(rawValue: 10006)
/// Consumer name in subject does not match durable name in request
public static let consumerDurableNameNotMatchSubject = ErrorCode(rawValue: 10017)
/// Insufficient memory resources available
public static let memoryResourcesExceeded = ErrorCode(rawValue: 10028)
/// Stream mirrors can not contain filtered subjects
public static let mirrorWithSubjectFilters = ErrorCode(rawValue: 10033)
/// Stream create failed with a string
public static let streamCreate = ErrorCode(rawValue: 10049)
/// Server is not a member of the cluster
public static let clusterServerNotMember = ErrorCode(rawValue: 10044)
/// No message found
public static let noMessageFound = ErrorCode(rawValue: 10037)
/// Deliver subject not valid
public static let snapshotDeliverSubjectInvalid = ErrorCode(rawValue: 10015)
/// General stream failure
public static let streamGeneralError = ErrorCode(rawValue: 10051)
/// Invalid stream config
public static let streamInvalidConfig = ErrorCode(rawValue: 10052)
/// Replicas > 1 not supported in non-clustered mode
public static let streamReplicasNotSupported = ErrorCode(rawValue: 10074)
/// Stream message delete failed
public static let streamMessageDeleteFailed = ErrorCode(rawValue: 10057)
/// Peer remap failed
public static let peerRemap = ErrorCode(rawValue: 10075)
/// Stream store failed
public static let streamStoreFailed = ErrorCode(rawValue: 10077)
/// Consumer config required
public static let consumerConfigRequired = ErrorCode(rawValue: 10078)
/// Consumer deliver subject has wildcards
public static let consumerDeliverToWildcards = ErrorCode(rawValue: 10079)
/// Consumer in push mode can not set max waiting
public static let consumerPushMaxWaiting = ErrorCode(rawValue: 10080)
/// Consumer deliver subject forms a cycle
public static let consumerDeliverCycle = ErrorCode(rawValue: 10081)
/// Consumer requires ack policy for max ack pending
public static let consumerMaxPendingAckPolicyRequired = ErrorCode(rawValue: 10082)
/// Consumer idle heartbeat needs to be >= 100ms
public static let consumerSmallHeartbeat = ErrorCode(rawValue: 10083)
/// Consumer in pull mode requires ack policy
public static let consumerPullRequiresAck = ErrorCode(rawValue: 10084)
/// Consumer in pull mode requires a durable name
public static let consumerPullNotDurable = ErrorCode(rawValue: 10085)
/// Consumer in pull mode can not have rate limit set
public static let consumerPullWithRateLimit = ErrorCode(rawValue: 10086)
/// Consumer max waiting needs to be positive
public static let consumerMaxWaitingNegative = ErrorCode(rawValue: 10087)
/// Consumer idle heartbeat requires a push based consumer
public static let consumerHeartbeatRequiresPush = ErrorCode(rawValue: 10088)
/// Consumer flow control requires a push based consumer
public static let consumerFlowControlRequiresPush = ErrorCode(rawValue: 10089)
/// Consumer direct requires a push based consumer
public static let consumerDirectRequiresPush = ErrorCode(rawValue: 10090)
/// Consumer direct requires an ephemeral consumer
public static let consumerDirectRequiresEphemeral = ErrorCode(rawValue: 10091)
/// Consumer direct on a mapped consumer
public static let consumerOnMapped = ErrorCode(rawValue: 10092)
/// Consumer filter subject is not a valid subset of the interest subjects
public static let consumerFilterNotSubset = ErrorCode(rawValue: 10093)
/// Invalid consumer policy
public static let consumerInvalidPolicy = ErrorCode(rawValue: 10094)
/// Failed to parse consumer sampling configuration
public static let consumerInvalidSampling = ErrorCode(rawValue: 10095)
/// Stream not valid
public static let streamInvalid = ErrorCode(rawValue: 10096)
/// Workqueue stream requires explicit ack
public static let consumerWqRequiresExplicitAck = ErrorCode(rawValue: 10098)
/// Multiple non-filtered consumers not allowed on workqueue stream
public static let consumerWqMultipleUnfiltered = ErrorCode(rawValue: 10099)
/// Filtered consumer not unique on workqueue stream
public static let consumerWqConsumerNotUnique = ErrorCode(rawValue: 10100)
/// Consumer must be deliver all on workqueue stream
public static let consumerWqConsumerNotDeliverAll = ErrorCode(rawValue: 10101)
/// Consumer name is too long
public static let consumerNameTooLong = ErrorCode(rawValue: 10102)
/// Durable name can not contain token separators and wildcards
public static let consumerBadDurableName = ErrorCode(rawValue: 10103)
/// Error creating store for consumer
public static let consumerStoreFailed = ErrorCode(rawValue: 10104)
/// Consumer already exists and is still active
public static let consumerExistingActive = ErrorCode(rawValue: 10105)
/// Consumer replacement durable config not the same
public static let consumerReplacementWithDifferentName = ErrorCode(rawValue: 10106)
/// Consumer description is too long
public static let consumerDescriptionTooLong = ErrorCode(rawValue: 10107)
/// Header size exceeds maximum allowed of 64k
public static let streamHeaderExceedsMaximum = ErrorCode(rawValue: 10097)
/// Consumer with flow control also needs heartbeats
public static let consumerWithFlowControlNeedsHeartbeats = ErrorCode(rawValue: 10108)
/// Invalid operation on sealed stream
public static let streamSealed = ErrorCode(rawValue: 10109)
/// Stream purge failed
public static let streamPurgeFailed = ErrorCode(rawValue: 10110)
/// Stream rollup failed
public static let streamRollupFailed = ErrorCode(rawValue: 10111)
/// Invalid push consumer deliver subject
public static let consumerInvalidDeliverSubject = ErrorCode(rawValue: 10112)
/// Account requires a stream config to have max bytes set
public static let streamMaxBytesRequired = ErrorCode(rawValue: 10113)
/// Consumer max request batch needs to be > 0
public static let consumerMaxRequestBatchNegative = ErrorCode(rawValue: 10114)
/// Consumer max request expires needs to be >= 1ms
public static let consumerMaxRequestExpiresToSmall = ErrorCode(rawValue: 10115)
/// Max deliver is required to be > length of backoff values
public static let consumerMaxDeliverBackoff = ErrorCode(rawValue: 10116)
/// Subject details would exceed maximum allowed
public static let streamInfoMaxSubjects = ErrorCode(rawValue: 10117)
/// Stream is offline
public static let streamOffline = ErrorCode(rawValue: 10118)
/// Consumer is offline
public static let consumerOffline = ErrorCode(rawValue: 10119)
/// No jetstream default or applicable tiered limit present
public static let noLimits = ErrorCode(rawValue: 10120)
/// Consumer max ack pending exceeds system limit
public static let consumerMaxPendingAckExcess = ErrorCode(rawValue: 10121)
/// Stream max bytes exceeds account limit max stream bytes
public static let streamMaxStreamBytesExceeded = ErrorCode(rawValue: 10122)
/// Can not move and scale a stream in a single update
public static let streamMoveAndScale = ErrorCode(rawValue: 10123)
/// Stream move already in progress
public static let streamMoveInProgress = ErrorCode(rawValue: 10124)
/// Consumer max request batch exceeds server limit
public static let consumerMaxRequestBatchExceeded = ErrorCode(rawValue: 10125)
/// Consumer config replica count exceeds parent stream
public static let consumerReplicasExceedsStream = ErrorCode(rawValue: 10126)
/// Consumer name can not contain path separators
public static let consumerNameContainsPathSeparators = ErrorCode(rawValue: 10127)
/// Stream name can not contain path separators
public static let streamNameContainsPathSeparators = ErrorCode(rawValue: 10128)
/// Stream move not in progress
public static let streamMoveNotInProgress = ErrorCode(rawValue: 10129)
/// Stream name already in use, cannot restore
public static let streamNameExistRestoreFailed = ErrorCode(rawValue: 10130)
/// Consumer create request did not match filtered subject from create subject
public static let consumerCreateFilterSubjectMismatch = ErrorCode(rawValue: 10131)
/// Consumer durable and name have to be equal if both are provided
public static let consumerCreateDurableAndNameMismatch = ErrorCode(rawValue: 10132)
/// Replicas count cannot be negative
public static let replicasCountCannotBeNegative = ErrorCode(rawValue: 10133)
/// Consumer config replicas must match interest retention stream's replicas
public static let consumerReplicasShouldMatchStream = ErrorCode(rawValue: 10134)
/// Consumer metadata exceeds maximum size
public static let consumerMetadataLength = ErrorCode(rawValue: 10135)
/// Consumer cannot have both filter_subject and filter_subjects specified
public static let consumerDuplicateFilterSubjects = ErrorCode(rawValue: 10136)
/// Consumer with multiple subject filters cannot use subject based api
public static let consumerMultipleFiltersNotAllowed = ErrorCode(rawValue: 10137)
/// Consumer subject filters cannot overlap
public static let consumerOverlappingSubjectFilters = ErrorCode(rawValue: 10138)
/// Consumer filter in filter_subjects cannot be empty
public static let consumerEmptyFilter = ErrorCode(rawValue: 10139)
/// Duplicate source configuration detected
public static let sourceDuplicateDetected = ErrorCode(rawValue: 10140)
/// Sourced stream name is invalid
public static let sourceInvalidStreamName = ErrorCode(rawValue: 10141)
/// Mirrored stream name is invalid
public static let mirrorInvalidStreamName = ErrorCode(rawValue: 10142)
/// Source with multiple subject transforms cannot also have a single subject filter
public static let sourceMultipleFiltersNotAllowed = ErrorCode(rawValue: 10144)
/// Source subject filter is invalid
public static let sourceInvalidSubjectFilter = ErrorCode(rawValue: 10145)
/// Source transform destination is invalid
public static let sourceInvalidTransformDestination = ErrorCode(rawValue: 10146)
/// Source filters cannot overlap
public static let sourceOverlappingSubjectFilters = ErrorCode(rawValue: 10147)
/// Consumer already exists
public static let consumerAlreadyExists = ErrorCode(rawValue: 10148)
/// Consumer does not exist
public static let consumerDoesNotExist = ErrorCode(rawValue: 10149)
/// Mirror with multiple subject transforms cannot also have a single subject filter
public static let mirrorMultipleFiltersNotAllowed = ErrorCode(rawValue: 10150)
/// Mirror subject filter is invalid
public static let mirrorInvalidSubjectFilter = ErrorCode(rawValue: 10151)
/// Mirror subject filters cannot overlap
public static let mirrorOverlappingSubjectFilters = ErrorCode(rawValue: 10152)
/// Consumer inactive threshold exceeds system limit
public static let consumerInactiveThresholdExcess = ErrorCode(rawValue: 10153)
}
extension ErrorCode {
// Encoding
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(rawValue)
}
// Decoding
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let decodedValue = try container.decode(UInt64.self)
self = ErrorCode(rawValue: decodedValue)
}
}
public enum Response<T: Codable>: Codable {
case success(T)
case error(JetStreamAPIResponse)
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
// Try to decode the expected success type T first
if let successResponse = try? container.decode(T.self) {
self = .success(successResponse)
return
}
// If that fails, try to decode ErrorResponse
let errorResponse = try container.decode(JetStreamAPIResponse.self)
self = .error(errorResponse)
return
}
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .success(let successData):
try container.encode(successData)
case .error(let errorData):
try container.encode(errorData)
}
}
}