use azure_core::http::StatusCode;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize)]
#[serde(transparent)]
pub struct SubStatusCode(u32);
impl SubStatusCode {
pub const fn new(code: u32) -> Self {
Self(code)
}
pub const fn value(&self) -> u32 {
self.0
}
pub fn from_header_value(s: &str) -> Option<Self> {
s.trim().parse::<u32>().ok().map(SubStatusCode)
}
pub fn name(&self, status_code: Option<StatusCode>) -> Option<&'static str> {
match self.0 {
0 => Some("Unknown"),
100 => Some("OperationInProgress"),
1002 => match u16::from(status_code?) {
404 => Some("ReadSessionNotAvailable"),
410 => Some("PartitionKeyRangeGone"),
_ => None,
},
1007 => match u16::from(status_code?) {
410 => Some("CompletingSplitOrMerge"),
503 => Some("InsufficientBindablePartitions"),
_ => None,
},
1008 => match u16::from(status_code?) {
403 => Some("DatabaseAccountNotFound"),
410 => Some("CompletingPartitionMigration"),
_ => None,
},
1012 => match u16::from(status_code?) {
403 => Some("RedundantDatabasePut"),
503 => Some("ComputeFederationNotFound"),
_ => None,
},
2001 => match u16::from(status_code?) {
204 => Some("MissedTargetLsn"),
412 => Some("SplitIsDisabled"),
_ => None,
},
2002 => match u16::from(status_code?) {
204 => Some("MissedTargetLsnOver100"),
412 => Some("CollectionsInPartitionGotUpdated"),
_ => None,
},
2003 => match u16::from(status_code?) {
204 => Some("MissedTargetLsnOver1000"),
412 => Some("CannotAcquirePkrangesLock"),
_ => None,
},
2004 => match u16::from(status_code?) {
204 => Some("MissedTargetLsnOver10000"),
412 => Some("ResourceNotFound"),
_ => None,
},
2011 => match u16::from(status_code?) {
204 => Some("MissedTargetGlobalCommittedLsn"),
412 => Some("StorageSplitConflictingWithNwayThroughputSplit"),
_ => None,
},
2012 => match u16::from(status_code?) {
204 => Some("MissedTargetGlobalCommittedLsnOver100"),
412 => Some("MergeIsDisabled"),
_ => None,
},
3207 => match u16::from(status_code?) {
409 => Some("ConfigurationNameAlreadyExists"),
429 => Some("PrepareTimeLimitExceeded"),
_ => None,
},
1013 => match u16::from(status_code?) {
400 => Some("PartitionKeyDefinitionNotSpecified"),
404 => Some("CollectionCreateInProgress"),
_ => None,
},
1024 => match u16::from(status_code?) {
400 => Some("CollectionRidMismatch"),
410 => Some("ArchivalPartitionNotPresent"),
_ => None,
},
1031 => match u16::from(status_code?) {
403 => Some("SystemPartitionKeyNotAllowed"),
404 => Some("PartitionMigratingCollectionDeleted"),
_ => None,
},
1034 => match u16::from(status_code?) {
403 => Some("ResourceSoftDeleted"),
404 => Some("PartitionMigrationSourcePartitionDeletedInMaster"),
_ => None,
},
6001 => match u16::from(status_code?) {
503 => Some("AggregatedHealthStateError"),
_ => Some("QueryWaitForSequentialProgress"),
},
2013 => Some("MissedTargetGlobalCommittedLsnOver1000"),
2014 => Some("MissedTargetGlobalCommittedLsnOver10000"),
1001 => Some("PartitionKeyMismatch"),
1004 => Some("CrossPartitionQueryNotServable"),
1016 => Some("SchemaOwnerIdMismatch"),
1017 => Some("SchemaHashOrIdMismatch"),
1018 => Some("PartitionKeyDefinitionMissingForAutopilot"),
0xFFFF => Some("ScriptCompileError"),
3205 => Some("AnotherOfferReplaceOperationIsInProgress"),
1101 => Some("HttpListenerException"),
1102 => Some("TransactionAlreadyActive"),
1103 => Some("InvalidTransactionId"),
1104 => Some("CrossCollectionTransactionNotSupported"),
1105 => Some("InvalidTopologyChangeRequest"),
3 => Some("WriteForbidden"),
1005 => Some("ProvisionLimitReached"),
1009 => Some("RedundantCollectionPut"),
1010 => Some("SharedThroughputDatabaseQuotaExceeded"),
1011 => Some("SharedThroughputOfferGrowNotNeeded"),
1014 => Some("PartitionKeyQuotaOverLimit"),
1015 => Some("OfferReplaceDisabledAutoScaleOffer"),
1019 => Some("SharedThroughputDatabaseCollectionCountExceeded"),
1020 => Some("SharedThroughputDatabaseCountExceeded"),
1021 => Some("ComputeInternalError"),
1026 => Some("ClientIdMismatch"),
1027 => Some("UniqueIndexReIndexInProgress"),
1028 => Some("ThroughputCapQuotaExceeded"),
1029 => Some("InvalidThroughputCapValue"),
1032 => Some("PartitionKeyDeleteRequestLimitExceeded"),
1033 => Some("LeakedPartition"),
1110 => Some("PatchConditionNotMet"),
1003 => Some("OwnerResourceNotFound"),
1023 => Some("StoreNotReady"),
1030 => Some("AuthTokenNotFoundInCache"),
1035 => Some("PartitionMigrationSharedThroughputDbPartitionNotFound"),
1036 => Some("PartitionMigrationPartitionResourceNotFound"),
1037 => Some("PartitionMigrationFailedToUpdateDns"),
1900 => Some("RequestPreempted"),
1006 => Some("ConflictWithControlPlane"),
3206 => Some("DatabaseNameAlreadyExists"),
3301 => Some("UniqueIndexConflict"),
3302 => Some("PartitionKeyHashCollisionForId"),
3303 => Some("AzureBackupVaultIncrementalBackupPaused"),
3304 => Some("AzureBackupVaultIncrementalBackupRestoreDisabled"),
3050 => Some("PartitionMigrationDocCountMismatchSourceTarget"),
3051 => Some("PartitionMigrationDocCountMismatchTargetReplicas"),
1000 => Some("NameCacheIsStale"),
1022 => Some("LeaseNotFound"),
2005 => Some("CannotAcquireOfferOwnerLock"),
2007 => Some("CannotAcquirePkrangeLock"),
2008 => Some("CannotAcquirePartitionLock"),
2015 => Some("TombstoneRecordsNotFound"),
2016 => Some("InvalidAccountStatus"),
2017 => Some("OfferValidationFailed"),
2018 => Some("CannotAcquireMasterPartitionAccessLock"),
2019 => Some("CannotAcquireInAccountRestoreLock"),
2020 => Some("CollectionStateChanged"),
2021 => Some("OfferScaledUpByUser"),
2101 => Some("CannotAcquireLogStoreLoadBalanceLock"),
3401 => Some("TransactionLimitExceeded"),
3402 => Some("BatchResponseSizeExceeded"),
3073 => Some("BwTreeIORateLimiter"),
3074 => Some("StalenessExceededBound"),
3075 => Some("ReplicationQueueFull"),
3076 => Some("BwTreeLogFullBackpressure"),
3077 => Some("ConnectionRateLimiter"),
3078 => Some("XPCompositeReplicator"),
3079 => Some("Unexpected"),
3080 => Some("AsyncReaderWriterLock"),
3081 => Some("ServiceModule"),
3082 => Some("ValueDoesNotMatchExpectedBound"),
3083 => Some("SinkPartitionValueDoesNotMatchExpectedBound"),
3084 => Some("StoredProcedureConcurrency"),
3085 => Some("RntbdClientChannel"),
3086 => Some("LogFlushQueueDepthBackpressure"),
3087 => Some("CheckpointQueueDepthBackpressure"),
3088 => Some("ThrottleDueToSplit"),
3089 => Some("AEQueueFull"),
3090 => Some("QuotaExceeded"),
3091 => Some("CollectionQuotaExceeded"),
3092 => Some("SystemResourceUnavailable"),
3093 => Some("PartitionedResourceQuotaExceeded"),
3094 => Some("ThrottleDueToResourceExhaustion"),
3095 => Some("ThrottleDueToStagingIndexQueueFull"),
3096 => Some("ThrottleDueToReplicationBackpressure"),
3097 => Some("CollectionQuotaExceededAutopilot"),
3098 => Some("LogStoreNoFreeSegments"),
3099 => Some("ThrottledByBlobRead"),
3100 => Some("OperationLogSizeTooBig"),
3101 => Some("ArchivalPartitionPendingCatchup"),
3102 => Some("ThrottleDueToTrafficRegulation"),
3103 => Some("ThrottleDueToTransportBufferUsage"),
3200 => Some("RUBudgetExceeded"),
3201 => Some("GatewayThrottled"),
3202 => Some("RUpmPartitionLimitExceeded"),
3203 => Some("RUpmSharedBudgetExceeded"),
3204 => Some("ThrottledOfferScaleDown"),
3208 => Some("ClientTcpChannelFull"),
3209 => Some("BWTermCountLimitExceeded"),
3210 => Some("RUBudgetExceededForMaster"),
3211 => Some("ThrottleDueToEncryptedRevokedStoreLogNotEmpty"),
3212 => Some("ThroughputBucketLimitExhausted"),
3213 => Some("TooManyThroughputBucketUpdates"),
3214 => Some("HotPartitionKeyThrottled"),
3300 => Some("MicrosoftFabricCUBudgetExceeded"),
5350 => Some("RbacAadGroupUnavailable"),
5351 => Some("AzureRbacAccessDecisionUnavailable"),
3001 => Some("ConfigurationNameNotEmpty"),
3002 => Some("ConfigurationOperationCancelled"),
3003 => Some("InvalidAccountConfiguration"),
3004 => Some("FederationDoesNotExistOrIsLocked"),
3010 => Some("PartitionFailoverErrorCode"),
3021 => Some("OperationManagerDequeuePumpStopped"),
3042 => Some("OperationCancelledWithNoRollback"),
3043 => Some("SplitTimedOut"),
5360 => Some("RbacDisabledDueToArmPath"),
1337 => Some("GoneException"),
1338 => Some("QuorumNotMet"),
1339 => Some("TooManyTentativeWritesToSatelliteRegion"),
9001 => Some("OperationPaused"),
9002 => Some("ServiceIsOffline"),
9003 => Some("InsufficientCapacity"),
6002 => Some("ApplicationHealthStateError"),
6003 => Some("HealthStateError"),
6004 => Some("UnhealthyEventFound"),
6005 => Some("ClusterHealthEmpty"),
6006 => Some("AllocationFailed"),
6007 => Some("OperationResultNull"),
6008 => Some("OperationResultUnexpected"),
6009 => Some("FabricNodesHealthError"),
4000 => Some("AadClientCredentialsGrantFailure"),
4001 => Some("AadServiceUnavailable"),
4002 => Some("KeyVaultAuthenticationFailure"),
4003 => Some("KeyVaultKeyNotFound"),
4004 => Some("KeyVaultServiceUnavailable"),
4005 => Some("KeyVaultWrapUnwrapFailure"),
4006 => Some("InvalidKeyVaultKeyUri"),
4007 => Some("InvalidInputBytes"),
4008 => Some("KeyVaultInternalServerError"),
4009 => Some("KeyVaultDnsNotResolved"),
4010 => Some("InvalidKeyVaultCertUri"),
4011 => Some("InvalidKeyVaultKeyAndCertUri"),
4012 => Some("CustomerKeyRotated"),
4013 => Some("MissingRequestParameter"),
4014 => Some("InvalidKeyVaultSecretUri"),
4015 => Some("UndefinedDefaultIdentity"),
4016 => Some("KeyVaultOutboundDeniedByNsp"),
4017 => Some("KeyVaultNotFound"),
4018 => Some("KeyDisabledOrExpired"),
4019 => Some("MasterServiceUnavailable"),
5000 => Some("MissingAuthHeader"),
5001 => Some("InvalidAuthHeaderFormat"),
5002 => Some("AadAuthDisabled"),
5003 => Some("AadTokenInvalidFormat"),
5004 => Some("AadTokenInvalidSignature"),
5005 => Some("AadTokenNotYetValid"),
5006 => Some("AadTokenExpired"),
5007 => Some("AadTokenInvalidIssuer"),
5008 => Some("AadTokenInvalidAudience"),
5009 => Some("AadTokenInvalidScope"),
5010 => Some("FailedToGetAadToken"),
5011 => Some("AadTokenMissingObjectIdentifier"),
5012 => Some("SasTokenAuthDisabled"),
5200 => Some("AadTokenInvalidSigningKey"),
5201 => Some("AadTokenGroupExpansionError"),
5202 => Some("LocalAuthDisabled"),
5203 => Some("LocalAuthDisabled"),
5300 => Some("RbacOperationNotSupported"),
5301 => Some("RbacUnauthorizedMetadataRequest"),
5302 => Some("RbacUnauthorizedNameBasedDataRequest"),
5303 => Some("RbacUnauthorizedRidBasedDataRequest"),
5304 => Some("RbacRidCannotBeResolved"),
5305 => Some("RbacMissingUserId"),
5306 => Some("RbacMissingAction"),
5307 => Some("NspInboundDenied"),
5325 => Some("MismatchingCollectionRidsOnMigratePartitionDuringMigration"),
5326 => Some("PartitionNotInMigratingStatusForMigratePartitionRequest"),
5327 => Some("MissingPartitionResourceOnCompleteMigration"),
5328 => Some("MissingPartitionResourceOnAbortMigration"),
5400 => Some("RbacRequestWasNotAuthorized"),
5401 => Some("InitialRetriableWriteRequestCompleted"),
5402 => Some("DuplicateRetriableWriteRequest"),
5403 => Some("ConflictOperationInUserTransaction"),
5404 => Some("RetriableWriteRequestResponseExpiredInPrimaryCache"),
6000 => Some("QueryRequestInitialized"),
6100 => Some("QueryExecutionInProgress"),
6200 => Some("QueryExecutionComplete"),
6300 => Some("CollectionTruncateNotAllowedDuringMerge"),
6050 => Some("InsufficientFabricPermissions"),
6051 => Some("FabricAuthorizationFailed"),
6052 => Some("FabricOperationUnsupported"),
6053 => Some("FabricTokenValidationFailed"),
6054 => Some("InvalidFabricAppId"),
6055 => Some("InvalidFabricTenantId"),
6056 => Some("InvalidFabricArtifactId"),
10001 => Some("GatewayEndpointUnavailable"),
10002 => Some("GatewayEndpointReadTimeout"),
10003 => Some("ThroughputControlRequestRateTooLarge"),
10004 => Some("OfferNotConfigured"),
10005 => Some("ThroughputControlBulkRequestRateTooLarge"),
10101 => Some("CustomSerializerException"),
10102 => Some("InvalidIdValue"),
20001 => Some("TransportGenerated410"),
20002 => Some("TimeoutGenerated410"),
20003 => Some("TransportGenerated503"),
20004 => Some("ClientCpuOverload"),
20005 => Some("ClientThreadStarvation"),
20006 => Some("ChannelClosed"),
20007 => Some("MalformedContinuationToken"),
20008 => Some("ClientOperationTimeout"),
20401 => Some("ClientGenerated401"),
20901 => Some("NegativeTimeoutProvided"),
20902 => Some("MissingPartitionKeyRangeIdInContext"),
20903 => Some("InvalidRegionsInSessionToken"),
20904 => Some("NonPartitionedResources"),
20905 => Some("PartitionKeyIsNull"),
20906 => Some("UnknownAuthorizationTokenKind"),
20907 => Some("RecreateRequestOnHttpClient"),
20908 => Some("InvalidBackendResponse"),
20909 => Some("UnknownQuorumResult"),
20910 => Some("InvalidResult"),
20911 => Some("TransitTimeout"),
20912 => Some("ClosedClient"),
20913 => Some("WriteRegionBarrierChangedMidOperation"),
20914 => Some("RegionScopedSessionContainerInBadState"),
21001 => Some("NameCacheIsStaleExceededRetryLimit"),
21002 => Some("PartitionKeyRangeGoneExceededRetryLimit"),
21003 => Some("CompletingSplitExceededRetryLimit"),
21004 => Some("CompletingPartitionMigrationExceededRetryLimit"),
21005 => Some("ServerGenerated410"),
21006 => Some("GlobalStrongWriteBarrierNotMet"),
21007 => Some("ReadQuorumNotMet"),
21008 => Some("ServerGenerated503"),
21009 => Some("NoValidStoreResponse"),
21010 => Some("ServerGenerated408"),
21011 => Some("ServerBarrierThrottled"),
21012 => Some("NRegionCommitWriteBarrierNotMet"),
13000 => Some("ThinProxyMultipleAccountsNotAllowed"),
13001 => Some("ThinProxyPublicEndpointDisabled"),
13008 => Some("ThinProxyGenerated401"),
13009 => Some("ThinProxyGenerated408"),
13010 => Some("ThinProxyRequestThrottled"),
13011 => Some("ThinProxyGenerated500"),
13012 => Some("ThinProxyGenerated503"),
_ => None,
}
}
pub const UNKNOWN: SubStatusCode = SubStatusCode(0);
pub const OPERATION_IN_PROGRESS: SubStatusCode = SubStatusCode(100);
pub const PARTITION_KEY_MISMATCH: SubStatusCode = SubStatusCode(1001);
pub const CROSS_PARTITION_QUERY_NOT_SERVABLE: SubStatusCode = SubStatusCode(1004);
pub const OFFER_REPLACE_IN_PROGRESS: SubStatusCode = SubStatusCode(3205);
pub const SCRIPT_COMPILE_ERROR: SubStatusCode = SubStatusCode(0xFFFF);
pub const HTTP_LISTENER_EXCEPTION: SubStatusCode = SubStatusCode(1101);
pub const SCHEMA_OWNER_ID_MISMATCH: SubStatusCode = SubStatusCode(1016);
pub const SCHEMA_HASH_OR_ID_MISMATCH: SubStatusCode = SubStatusCode(1017);
pub const PARTITION_KEY_DEFINITION_MISSING_FOR_AUTOPILOT: SubStatusCode = SubStatusCode(1018);
pub const PARTITION_KEY_DEFINITION_NOT_SPECIFIED: SubStatusCode = SubStatusCode(1013);
pub const COLLECTION_RID_MISMATCH: SubStatusCode = SubStatusCode(1024);
pub const TRANSACTION_ALREADY_ACTIVE: SubStatusCode = SubStatusCode(1102);
pub const INVALID_TRANSACTION_ID: SubStatusCode = SubStatusCode(1103);
pub const CROSS_COLLECTION_TRANSACTION_NOT_SUPPORTED: SubStatusCode = SubStatusCode(1104);
pub const INVALID_TOPOLOGY_CHANGE_REQUEST: SubStatusCode = SubStatusCode(1105);
pub const WRITE_FORBIDDEN: SubStatusCode = SubStatusCode(3);
pub const PROVISION_LIMIT_REACHED: SubStatusCode = SubStatusCode(1005);
pub const DATABASE_ACCOUNT_NOT_FOUND: SubStatusCode = SubStatusCode(1008);
pub const DATABASE_QUOTA_EXCEEDED: SubStatusCode = SubStatusCode(1010);
pub const THROUGHPUT_CAP_EXCEEDED: SubStatusCode = SubStatusCode(1028);
pub const INVALID_THROUGHPUT_CAP_VALUE: SubStatusCode = SubStatusCode(1029);
pub const REDUNDANT_COLLECTION_PUT: SubStatusCode = SubStatusCode(1009);
pub const SHARED_THROUGHPUT_OFFER_GROW_NOT_NEEDED: SubStatusCode = SubStatusCode(1011);
pub const COMPUTE_FEDERATION_NOT_FOUND: SubStatusCode = SubStatusCode(1012);
pub const PARTITION_KEY_QUOTA_OVER_LIMIT: SubStatusCode = SubStatusCode(1014);
pub const SHARED_THROUGHPUT_DATABASE_COLLECTION_COUNT_EXCEEDED: SubStatusCode =
SubStatusCode(1019);
pub const SHARED_THROUGHPUT_DATABASE_COUNT_EXCEEDED: SubStatusCode = SubStatusCode(1020);
pub const COMPUTE_INTERNAL_ERROR: SubStatusCode = SubStatusCode(1021);
pub const OFFER_REPLACE_DISABLED_AUTO_SCALE_OFFER: SubStatusCode = SubStatusCode(1015);
pub const CLIENT_ID_MISMATCH: SubStatusCode = SubStatusCode(1026);
pub const UNIQUE_INDEX_RE_INDEX_IN_PROGRESS: SubStatusCode = SubStatusCode(1027);
pub const PARTITION_KEY_DELETE_REQUEST_LIMIT_EXCEEDED: SubStatusCode = SubStatusCode(1032);
pub const LEAKED_PARTITION: SubStatusCode = SubStatusCode(1033);
pub const SYSTEM_PARTITION_KEY_NOT_ALLOWED: SubStatusCode = SubStatusCode(1031);
pub const RESOURCE_SOFT_DELETED: SubStatusCode = SubStatusCode(1034);
pub const PATCH_CONDITION_NOT_MET: SubStatusCode = SubStatusCode(1110);
pub const READ_SESSION_NOT_AVAILABLE: SubStatusCode = SubStatusCode(1002);
pub const OWNER_RESOURCE_NOT_FOUND: SubStatusCode = SubStatusCode(1003);
pub const COLLECTION_CREATE_IN_PROGRESS: SubStatusCode = SubStatusCode(1013);
pub const STORE_NOT_READY: SubStatusCode = SubStatusCode(1023);
pub const AUTH_TOKEN_NOT_FOUND_IN_CACHE: SubStatusCode = SubStatusCode(1030);
pub const ARCHIVAL_PARTITION_NOT_PRESENT: SubStatusCode = SubStatusCode(1024);
pub const PARTITION_MIGRATING_COLLECTION_DELETED: SubStatusCode = SubStatusCode(1031);
pub const PARTITION_MIGRATION_SOURCE_PARTITION_DELETED_IN_MASTER: SubStatusCode =
SubStatusCode(1034);
pub const PARTITION_MIGRATION_SHARED_THROUGHPUT_DB_PARTITION_NOT_FOUND: SubStatusCode =
SubStatusCode(1035);
pub const PARTITION_MIGRATION_PARTITION_RESOURCE_NOT_FOUND: SubStatusCode = SubStatusCode(1036);
pub const PARTITION_MIGRATION_FAILED_TO_UPDATE_DNS: SubStatusCode = SubStatusCode(1037);
pub const REQUEST_PREEMPTED: SubStatusCode = SubStatusCode(1900);
pub const CONFLICT_WITH_CONTROL_PLANE: SubStatusCode = SubStatusCode(1006);
pub const DATABASE_NAME_EXISTS: SubStatusCode = SubStatusCode(3206);
pub const PARTITION_KEY_HASH_COLLISION: SubStatusCode = SubStatusCode(3302);
pub const PARTITION_MIGRATION_DOC_COUNT_MISMATCH_SOURCE_TARGET: SubStatusCode =
SubStatusCode(3050);
pub const PARTITION_MIGRATION_DOC_COUNT_MISMATCH_TARGET_REPLICAS: SubStatusCode =
SubStatusCode(3051);
pub const UNIQUE_INDEX_CONFLICT: SubStatusCode = SubStatusCode(3301);
pub const AZURE_BACKUP_VAULT_INCREMENTAL_BACKUP_PAUSED: SubStatusCode = SubStatusCode(3303);
pub const AZURE_BACKUP_VAULT_INCREMENTAL_BACKUP_RESTORE_DISABLED: SubStatusCode =
SubStatusCode(3304);
pub const NAME_CACHE_STALE: SubStatusCode = SubStatusCode(1000);
pub const PARTITION_KEY_RANGE_GONE: SubStatusCode = SubStatusCode(1002);
pub const COMPLETING_SPLIT: SubStatusCode = SubStatusCode(1007);
pub const COMPLETING_PARTITION_MIGRATION: SubStatusCode = SubStatusCode(1008);
pub const LEASE_NOT_FOUND: SubStatusCode = SubStatusCode(1022);
pub const SPLIT_DISABLED: SubStatusCode = SubStatusCode(2001);
pub const RESOURCE_NOT_FOUND: SubStatusCode = SubStatusCode(2004);
pub const TOMBSTONE_RECORDS_NOT_FOUND: SubStatusCode = SubStatusCode(2015);
pub const COLLECTIONS_IN_PARTITION_GOT_UPDATED: SubStatusCode = SubStatusCode(2002);
pub const CANNOT_ACQUIRE_PKRANGES_LOCK: SubStatusCode = SubStatusCode(2003);
pub const CANNOT_ACQUIRE_OFFER_OWNER_LOCK: SubStatusCode = SubStatusCode(2005);
pub const CANNOT_ACQUIRE_PKRANGE_LOCK: SubStatusCode = SubStatusCode(2007);
pub const CANNOT_ACQUIRE_PARTITION_LOCK: SubStatusCode = SubStatusCode(2008);
pub const STORAGE_SPLIT_CONFLICTING_WITH_NWAY_THROUGHPUT_SPLIT: SubStatusCode =
SubStatusCode(2011);
pub const MERGE_DISABLED: SubStatusCode = SubStatusCode(2012);
pub const INVALID_ACCOUNT_STATUS: SubStatusCode = SubStatusCode(2016);
pub const OFFER_VALIDATION_FAILED: SubStatusCode = SubStatusCode(2017);
pub const CANNOT_ACQUIRE_MASTER_PARTITION_ACCESS_LOCK: SubStatusCode = SubStatusCode(2018);
pub const CANNOT_ACQUIRE_IN_ACCOUNT_RESTORE_LOCK: SubStatusCode = SubStatusCode(2019);
pub const COLLECTION_STATE_CHANGED: SubStatusCode = SubStatusCode(2020);
pub const OFFER_SCALED_UP_BY_USER: SubStatusCode = SubStatusCode(2021);
pub const CANNOT_ACQUIRE_LOG_STORE_LOAD_BALANCE_LOCK: SubStatusCode = SubStatusCode(2101);
pub const TRANSACTION_LIMIT_EXCEEDED: SubStatusCode = SubStatusCode(3401);
pub const BATCH_RESPONSE_SIZE_EXCEEDED: SubStatusCode = SubStatusCode(3402);
pub const RU_BUDGET_EXCEEDED: SubStatusCode = SubStatusCode(3200);
pub const GATEWAY_THROTTLED: SubStatusCode = SubStatusCode(3201);
pub const PREPARE_TIME_EXCEEDED: SubStatusCode = SubStatusCode(3207);
pub const CLIENT_TCP_CHANNEL_FULL: SubStatusCode = SubStatusCode(3208);
pub const STORED_PROCEDURE_CONCURRENCY: SubStatusCode = SubStatusCode(3084);
pub const THROTTLE_DUE_TO_SPLIT: SubStatusCode = SubStatusCode(3088);
pub const SYSTEM_RESOURCE_UNAVAILABLE: SubStatusCode = SubStatusCode(3092);
pub const BW_TERM_COUNT_LIMIT_EXCEEDED: SubStatusCode = SubStatusCode(3209);
pub const BW_TREE_IO_RATE_LIMITER: SubStatusCode = SubStatusCode(3073);
pub const STALENESS_EXCEEDED_BOUND: SubStatusCode = SubStatusCode(3074);
pub const REPLICATION_QUEUE_FULL: SubStatusCode = SubStatusCode(3075);
pub const BW_TREE_LOG_FULL_BACKPRESSURE: SubStatusCode = SubStatusCode(3076);
pub const CONNECTION_RATE_LIMITER: SubStatusCode = SubStatusCode(3077);
pub const XP_COMPOSITE_REPLICATOR: SubStatusCode = SubStatusCode(3078);
pub const UNEXPECTED_THROTTLE: SubStatusCode = SubStatusCode(3079);
pub const ASYNC_READER_WRITER_LOCK: SubStatusCode = SubStatusCode(3080);
pub const SERVICE_MODULE: SubStatusCode = SubStatusCode(3081);
pub const VALUE_DOES_NOT_MATCH_EXPECTED_BOUND: SubStatusCode = SubStatusCode(3082);
pub const SINK_PARTITION_VALUE_DOES_NOT_MATCH_EXPECTED_BOUND: SubStatusCode =
SubStatusCode(3083);
pub const RNTBD_CLIENT_CHANNEL: SubStatusCode = SubStatusCode(3085);
pub const LOG_FLUSH_QUEUE_DEPTH_BACKPRESSURE: SubStatusCode = SubStatusCode(3086);
pub const CHECKPOINT_QUEUE_DEPTH_BACKPRESSURE: SubStatusCode = SubStatusCode(3087);
pub const AE_QUEUE_FULL: SubStatusCode = SubStatusCode(3089);
pub const QUOTA_EXCEEDED: SubStatusCode = SubStatusCode(3090);
pub const COLLECTION_QUOTA_EXCEEDED: SubStatusCode = SubStatusCode(3091);
pub const PARTITIONED_RESOURCE_QUOTA_EXCEEDED: SubStatusCode = SubStatusCode(3093);
pub const THROTTLE_DUE_TO_RESOURCE_EXHAUSTION: SubStatusCode = SubStatusCode(3094);
pub const THROTTLE_DUE_TO_STAGING_INDEX_QUEUE_FULL: SubStatusCode = SubStatusCode(3095);
pub const THROTTLE_DUE_TO_REPLICATION_BACKPRESSURE: SubStatusCode = SubStatusCode(3096);
pub const COLLECTION_QUOTA_EXCEEDED_AUTOPILOT: SubStatusCode = SubStatusCode(3097);
pub const LOG_STORE_NO_FREE_SEGMENTS: SubStatusCode = SubStatusCode(3098);
pub const THROTTLED_BY_BLOB_READ: SubStatusCode = SubStatusCode(3099);
pub const OPERATION_LOG_SIZE_TOO_BIG: SubStatusCode = SubStatusCode(3100);
pub const ARCHIVAL_PARTITION_PENDING_CATCHUP: SubStatusCode = SubStatusCode(3101);
pub const THROTTLE_DUE_TO_TRAFFIC_REGULATION: SubStatusCode = SubStatusCode(3102);
pub const THROTTLE_DUE_TO_TRANSPORT_BUFFER_USAGE: SubStatusCode = SubStatusCode(3103);
pub const RUPM_PARTITION_LIMIT_EXCEEDED: SubStatusCode = SubStatusCode(3202);
pub const RUPM_SHARED_BUDGET_EXCEEDED: SubStatusCode = SubStatusCode(3203);
pub const THROTTLED_OFFER_SCALE_DOWN: SubStatusCode = SubStatusCode(3204);
pub const RU_BUDGET_EXCEEDED_FOR_MASTER: SubStatusCode = SubStatusCode(3210);
pub const THROTTLE_DUE_TO_ENCRYPTED_REVOKED_STORE_LOG_NOT_EMPTY: SubStatusCode =
SubStatusCode(3211);
pub const THROUGHPUT_BUCKET_LIMIT_EXHAUSTED: SubStatusCode = SubStatusCode(3212);
pub const TOO_MANY_THROUGHPUT_BUCKET_UPDATES: SubStatusCode = SubStatusCode(3213);
pub const HOT_PARTITION_KEY_THROTTLED: SubStatusCode = SubStatusCode(3214);
pub const INVALID_ACCOUNT_CONFIGURATION: SubStatusCode = SubStatusCode(3003);
pub const CONFIGURATION_NAME_NOT_EMPTY: SubStatusCode = SubStatusCode(3001);
pub const CONFIGURATION_OPERATION_CANCELLED: SubStatusCode = SubStatusCode(3002);
pub const FEDERATION_DOES_NOT_EXIST_OR_IS_LOCKED: SubStatusCode = SubStatusCode(3004);
pub const PARTITION_FAILOVER_ERROR_CODE: SubStatusCode = SubStatusCode(3010);
pub const RBAC_DISABLED_DUE_TO_ARM_PATH: SubStatusCode = SubStatusCode(5360);
pub const OPERATION_PAUSED: SubStatusCode = SubStatusCode(9001);
pub const INSUFFICIENT_CAPACITY: SubStatusCode = SubStatusCode(9003);
pub const INSUFFICIENT_BINDABLE_PARTITIONS: SubStatusCode = SubStatusCode(1007);
pub const SERVICE_IS_OFFLINE: SubStatusCode = SubStatusCode(9002);
pub const GONE_EXCEPTION: SubStatusCode = SubStatusCode(1337);
pub const QUORUM_NOT_MET: SubStatusCode = SubStatusCode(1338);
pub const TOO_MANY_TENTATIVE_WRITES_TO_SATELLITE_REGION: SubStatusCode = SubStatusCode(1339);
pub const GATEWAY_ENDPOINT_UNAVAILABLE: SubStatusCode = SubStatusCode(10001);
pub const GATEWAY_ENDPOINT_READ_TIMEOUT: SubStatusCode = SubStatusCode(10002);
pub const THROUGHPUT_CONTROL_REQUEST_RATE_TOO_LARGE: SubStatusCode = SubStatusCode(10003);
pub const OFFER_NOT_CONFIGURED: SubStatusCode = SubStatusCode(10004);
pub const TRANSPORT_GENERATED_410: SubStatusCode = SubStatusCode(20001);
pub const TIMEOUT_GENERATED_410: SubStatusCode = SubStatusCode(20002);
pub const TRANSPORT_GENERATED_503: SubStatusCode = SubStatusCode(20003);
pub const CLIENT_GENERATED_401: SubStatusCode = SubStatusCode(20401);
pub const CLIENT_CPU_OVERLOAD: SubStatusCode = SubStatusCode(20004);
pub const CLIENT_THREAD_STARVATION: SubStatusCode = SubStatusCode(20005);
pub const CHANNEL_CLOSED: SubStatusCode = SubStatusCode(20006);
pub const MALFORMED_CONTINUATION_TOKEN: SubStatusCode = SubStatusCode(20007);
pub const CLIENT_OPERATION_TIMEOUT: SubStatusCode = SubStatusCode(20008);
pub const TRANSIT_TIMEOUT: SubStatusCode = SubStatusCode(20911);
pub const CLOSED_CLIENT: SubStatusCode = SubStatusCode(20912);
pub const NAME_CACHE_STALE_EXCEEDED_RETRY_LIMIT: SubStatusCode = SubStatusCode(21001);
pub const PARTITION_KEY_RANGE_GONE_EXCEEDED_RETRY_LIMIT: SubStatusCode = SubStatusCode(21002);
pub const COMPLETING_SPLIT_EXCEEDED_RETRY_LIMIT: SubStatusCode = SubStatusCode(21003);
pub const COMPLETING_PARTITION_MIGRATION_EXCEEDED_RETRY_LIMIT: SubStatusCode =
SubStatusCode(21004);
pub const SERVER_GENERATED_410: SubStatusCode = SubStatusCode(21005);
pub const GLOBAL_STRONG_WRITE_BARRIER_NOT_MET: SubStatusCode = SubStatusCode(21006);
pub const READ_QUORUM_NOT_MET: SubStatusCode = SubStatusCode(21007);
pub const SERVER_GENERATED_503: SubStatusCode = SubStatusCode(21008);
pub const NO_VALID_STORE_RESPONSE: SubStatusCode = SubStatusCode(21009);
pub const SERVER_GENERATED_408: SubStatusCode = SubStatusCode(21010);
pub const SERVER_BARRIER_THROTTLED: SubStatusCode = SubStatusCode(21011);
pub const AAD_TOKEN_EXPIRED: SubStatusCode = SubStatusCode(5006);
pub const LOCAL_AUTH_DISABLED: SubStatusCode = SubStatusCode(5202);
pub const RBAC_REQUEST_NOT_AUTHORIZED: SubStatusCode = SubStatusCode(5400);
pub const INVALID_KEY_VAULT_CERT_URI: SubStatusCode = SubStatusCode(4010);
pub const INVALID_KEY_VAULT_KEY_AND_CERT_URI: SubStatusCode = SubStatusCode(4011);
pub const CUSTOMER_KEY_ROTATED: SubStatusCode = SubStatusCode(4012);
pub const MISSING_REQUEST_PARAMETER: SubStatusCode = SubStatusCode(4013);
pub const INVALID_KEY_VAULT_SECRET_URI: SubStatusCode = SubStatusCode(4014);
pub const UNDEFINED_DEFAULT_IDENTITY: SubStatusCode = SubStatusCode(4015);
pub const KEY_VAULT_OUTBOUND_DENIED_BY_NSP: SubStatusCode = SubStatusCode(4016);
pub const KEY_VAULT_NOT_FOUND: SubStatusCode = SubStatusCode(4017);
pub const KEY_DISABLED_OR_EXPIRED: SubStatusCode = SubStatusCode(4018);
pub const MASTER_SERVICE_UNAVAILABLE: SubStatusCode = SubStatusCode(4019);
pub const MISMATCHING_COLLECTION_RIDS_ON_MIGRATE_PARTITION: SubStatusCode = SubStatusCode(5325);
pub const PARTITION_NOT_IN_MIGRATING_STATUS: SubStatusCode = SubStatusCode(5326);
pub const MISSING_PARTITION_RESOURCE_ON_COMPLETE_MIGRATION: SubStatusCode = SubStatusCode(5327);
pub const MISSING_PARTITION_RESOURCE_ON_ABORT_MIGRATION: SubStatusCode = SubStatusCode(5328);
pub const RBAC_AAD_GROUP_UNAVAILABLE: SubStatusCode = SubStatusCode(5350);
pub const AZURE_RBAC_ACCESS_DECISION_UNAVAILABLE: SubStatusCode = SubStatusCode(5351);
pub const INITIAL_RETRIABLE_WRITE_REQUEST_COMPLETED: SubStatusCode = SubStatusCode(5401);
pub const DUPLICATE_RETRIABLE_WRITE_REQUEST: SubStatusCode = SubStatusCode(5402);
pub const CONFLICT_OPERATION_IN_USER_TRANSACTION: SubStatusCode = SubStatusCode(5403);
pub const RETRIABLE_WRITE_RESPONSE_EXPIRED_IN_PRIMARY_CACHE: SubStatusCode =
SubStatusCode(5404);
pub const QUERY_REQUEST_INITIALIZED: SubStatusCode = SubStatusCode(6000);
pub const QUERY_WAIT_FOR_SEQUENTIAL_PROGRESS: SubStatusCode = SubStatusCode(6001);
pub const QUERY_EXECUTION_IN_PROGRESS: SubStatusCode = SubStatusCode(6100);
pub const QUERY_EXECUTION_COMPLETE: SubStatusCode = SubStatusCode(6200);
pub const COLLECTION_TRUNCATE_NOT_ALLOWED_DURING_MERGE: SubStatusCode = SubStatusCode(6300);
}
impl Default for SubStatusCode {
fn default() -> Self {
Self::UNKNOWN
}
}
impl fmt::Debug for SubStatusCode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.name(None) {
Some(name) => write!(f, "SubStatusCode::{}({})", name, self.0),
None => write!(f, "SubStatusCode({})", self.0),
}
}
}
impl fmt::Display for SubStatusCode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.name(None) {
Some(name) => write!(f, "{} ({})", name, self.0),
None => write!(f, "{}", self.0),
}
}
}
impl From<u32> for SubStatusCode {
fn from(value: u32) -> Self {
SubStatusCode(value)
}
}
impl From<SubStatusCode> for u32 {
fn from(code: SubStatusCode) -> Self {
code.0
}
}
#[derive(Clone, Copy, Eq, PartialEq, Hash)]
pub struct CosmosStatus {
status_code: StatusCode,
sub_status: Option<SubStatusCode>,
}
impl CosmosStatus {
pub fn new(status_code: StatusCode) -> Self {
Self {
status_code,
sub_status: None,
}
}
pub fn with_sub_status(mut self, sub_status_code: u32) -> Self {
self.sub_status = Some(SubStatusCode::new(sub_status_code));
self
}
pub(crate) fn from_parts(status_code: StatusCode, sub_status: Option<SubStatusCode>) -> Self {
Self {
status_code,
sub_status,
}
}
pub fn status_code(&self) -> StatusCode {
self.status_code
}
pub fn sub_status(&self) -> Option<SubStatusCode> {
self.sub_status
}
pub fn is_success(&self) -> bool {
self.status_code.is_success()
}
pub fn is_throttled(&self) -> bool {
u16::from(self.status_code) == 429
}
pub fn is_gone(&self) -> bool {
u16::from(self.status_code) == 410
}
pub fn is_not_found(&self) -> bool {
u16::from(self.status_code) == 404
}
pub fn is_write_forbidden(&self) -> bool {
u16::from(self.status_code) == 403
&& self.sub_status == Some(SubStatusCode::WRITE_FORBIDDEN)
}
pub fn is_read_session_not_available(&self) -> bool {
u16::from(self.status_code) == 404
&& self.sub_status == Some(SubStatusCode::READ_SESSION_NOT_AVAILABLE)
}
pub fn is_partition_key_range_gone(&self) -> bool {
u16::from(self.status_code) == 410
&& self.sub_status == Some(SubStatusCode::PARTITION_KEY_RANGE_GONE)
}
pub fn is_transport_generated_503(&self) -> bool {
u16::from(self.status_code) == 503
&& self.sub_status == Some(SubStatusCode::TRANSPORT_GENERATED_503)
}
pub fn name(&self) -> Option<&'static str> {
let sub = self.sub_status?;
sub.name(Some(self.status_code))
}
pub const TRANSPORT_GENERATED_503: CosmosStatus = CosmosStatus {
status_code: StatusCode::ServiceUnavailable,
sub_status: Some(SubStatusCode::TRANSPORT_GENERATED_503),
};
pub const CLIENT_GENERATED_401: CosmosStatus = CosmosStatus {
status_code: StatusCode::Unauthorized,
sub_status: Some(SubStatusCode::CLIENT_GENERATED_401),
};
pub const READ_SESSION_NOT_AVAILABLE: CosmosStatus = CosmosStatus {
status_code: StatusCode::NotFound,
sub_status: Some(SubStatusCode::READ_SESSION_NOT_AVAILABLE),
};
pub const WRITE_FORBIDDEN: CosmosStatus = CosmosStatus {
status_code: StatusCode::Forbidden,
sub_status: Some(SubStatusCode::WRITE_FORBIDDEN),
};
pub const PARTITION_KEY_RANGE_GONE: CosmosStatus = CosmosStatus {
status_code: StatusCode::Gone,
sub_status: Some(SubStatusCode::PARTITION_KEY_RANGE_GONE),
};
pub const NAME_CACHE_STALE: CosmosStatus = CosmosStatus {
status_code: StatusCode::Gone,
sub_status: Some(SubStatusCode::NAME_CACHE_STALE),
};
pub const COMPLETING_SPLIT: CosmosStatus = CosmosStatus {
status_code: StatusCode::Gone,
sub_status: Some(SubStatusCode::COMPLETING_SPLIT),
};
pub const COMPLETING_PARTITION_MIGRATION: CosmosStatus = CosmosStatus {
status_code: StatusCode::Gone,
sub_status: Some(SubStatusCode::COMPLETING_PARTITION_MIGRATION),
};
pub const RU_BUDGET_EXCEEDED: CosmosStatus = CosmosStatus {
status_code: StatusCode::TooManyRequests,
sub_status: Some(SubStatusCode::RU_BUDGET_EXCEEDED),
};
}
impl fmt::Debug for CosmosStatus {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let status_u16: u16 = self.status_code.into();
match (self.sub_status, self.name()) {
(Some(sub), Some(name)) => {
write!(f, "CosmosStatus({}/{} {})", status_u16, sub.value(), name)
}
(Some(sub), None) => write!(f, "CosmosStatus({}/{})", status_u16, sub.value()),
(None, _) => write!(f, "CosmosStatus({})", status_u16),
}
}
}
impl fmt::Display for CosmosStatus {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let status_u16: u16 = self.status_code.into();
match (self.sub_status, self.name()) {
(Some(sub), Some(name)) => write!(f, "{}/{} ({})", status_u16, sub.value(), name),
(Some(sub), None) => write!(f, "{}/{}", status_u16, sub.value()),
(None, _) => write!(f, "{}", status_u16),
}
}
}
impl Serialize for CosmosStatus {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
use serde::ser::SerializeStruct;
let mut s = serializer.serialize_struct("CosmosStatus", 1)?;
s.serialize_field("status", &self.to_string())?;
s.end()
}
}
impl<'de> Deserialize<'de> for CosmosStatus {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
#[derive(Deserialize)]
struct Helper {
status: Option<String>,
status_code: Option<u16>,
sub_status_code: Option<u32>,
}
let h = Helper::deserialize(deserializer)?;
if let Some(status_code) = h.status_code {
return Ok(CosmosStatus {
status_code: StatusCode::from(status_code),
sub_status: h.sub_status_code.map(SubStatusCode::new),
});
}
if let Some(status) = h.status {
let normalized = status
.split_once(' ')
.map_or(status.as_str(), |(left, _)| left);
if let Some((status_code, sub_status_code)) = normalized.split_once('/') {
let status_code = status_code
.parse::<u16>()
.map_err(serde::de::Error::custom)?;
let sub_status_code = sub_status_code
.parse::<u32>()
.map_err(serde::de::Error::custom)?;
return Ok(CosmosStatus {
status_code: StatusCode::from(status_code),
sub_status: Some(SubStatusCode::new(sub_status_code)),
});
}
let status_code = normalized
.parse::<u16>()
.map_err(serde::de::Error::custom)?;
return Ok(CosmosStatus {
status_code: StatusCode::from(status_code),
sub_status: None,
});
}
Err(serde::de::Error::custom(
"CosmosStatus must include status or status_code",
))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn new_without_sub_status() {
let status = CosmosStatus::new(StatusCode::Ok);
assert_eq!(status.status_code(), StatusCode::Ok);
assert!(status.sub_status().is_none());
assert!(status.is_success());
assert!(status.name().is_none());
}
#[test]
fn with_sub_status_unambiguous() {
let status = CosmosStatus::new(StatusCode::TooManyRequests).with_sub_status(3200);
assert_eq!(status.status_code(), StatusCode::TooManyRequests);
assert_eq!(status.sub_status(), Some(SubStatusCode::RU_BUDGET_EXCEEDED));
assert!(status.is_throttled());
assert_eq!(status.name(), Some("RUBudgetExceeded"));
}
#[test]
fn disambiguates_1002_404_vs_410() {
let not_found = CosmosStatus::new(StatusCode::NotFound).with_sub_status(1002);
assert_eq!(not_found.name(), Some("ReadSessionNotAvailable"));
assert!(not_found.is_read_session_not_available());
assert!(!not_found.is_partition_key_range_gone());
let gone = CosmosStatus::new(StatusCode::Gone).with_sub_status(1002);
assert_eq!(gone.name(), Some("PartitionKeyRangeGone"));
assert!(gone.is_partition_key_range_gone());
assert!(!gone.is_read_session_not_available());
}
#[test]
fn disambiguates_1008_403_vs_410() {
let forbidden = CosmosStatus::new(StatusCode::Forbidden).with_sub_status(1008);
assert_eq!(forbidden.name(), Some("DatabaseAccountNotFound"));
let gone = CosmosStatus::new(StatusCode::Gone).with_sub_status(1008);
assert_eq!(gone.name(), Some("CompletingPartitionMigration"));
}
#[test]
fn well_known_constants() {
assert!(CosmosStatus::TRANSPORT_GENERATED_503.is_transport_generated_503());
assert!(CosmosStatus::READ_SESSION_NOT_AVAILABLE.is_read_session_not_available());
assert!(CosmosStatus::PARTITION_KEY_RANGE_GONE.is_partition_key_range_gone());
assert!(CosmosStatus::WRITE_FORBIDDEN.is_write_forbidden());
assert!(CosmosStatus::RU_BUDGET_EXCEEDED.is_throttled());
}
#[test]
fn is_success() {
assert!(CosmosStatus::new(StatusCode::Ok).is_success());
assert!(CosmosStatus::new(StatusCode::Created).is_success());
assert!(!CosmosStatus::new(StatusCode::NotFound).is_success());
assert!(!CosmosStatus::RU_BUDGET_EXCEEDED.is_success());
}
#[test]
fn display_with_name() {
let status = CosmosStatus::new(StatusCode::TooManyRequests).with_sub_status(3200);
assert_eq!(format!("{}", status), "429/3200 (RUBudgetExceeded)");
}
#[test]
fn display_without_sub_status() {
let status = CosmosStatus::new(StatusCode::Ok);
assert_eq!(format!("{}", status), "200");
}
#[test]
fn display_unknown_sub_status() {
let status = CosmosStatus::new(StatusCode::Ok).with_sub_status(99999);
assert_eq!(format!("{}", status), "200/99999");
}
#[test]
fn debug_format() {
let status = CosmosStatus::new(StatusCode::NotFound).with_sub_status(1002);
assert_eq!(
format!("{:?}", status),
"CosmosStatus(404/1002 ReadSessionNotAvailable)"
);
}
#[test]
fn equality() {
assert_eq!(
CosmosStatus::new(StatusCode::NotFound).with_sub_status(1002),
CosmosStatus::READ_SESSION_NOT_AVAILABLE
);
assert_ne!(
CosmosStatus::new(StatusCode::NotFound).with_sub_status(1002),
CosmosStatus::new(StatusCode::Gone).with_sub_status(1002),
);
}
#[test]
fn serialization_roundtrip() {
let status = CosmosStatus::new(StatusCode::TooManyRequests).with_sub_status(3200);
let json = serde_json::to_string(&status).unwrap();
assert!(json.contains("\"status\":\"429/3200 (RUBudgetExceeded)\""));
let deserialized: CosmosStatus = serde_json::from_str(&json).unwrap();
assert_eq!(deserialized, status);
}
#[test]
fn serialization_without_sub_status() {
let status = CosmosStatus::new(StatusCode::Ok);
let json = serde_json::to_string(&status).unwrap();
assert!(json.contains("\"status\":\"200\""));
}
#[test]
fn new_with_zero_status() {
let status = CosmosStatus::new(StatusCode::from(0));
assert_eq!(u16::from(status.status_code()), 0);
assert!(status.sub_status().is_none());
}
#[test]
fn new_and_value() {
let code = SubStatusCode::new(1002);
assert_eq!(code.value(), 1002);
}
#[test]
fn from_header_value_valid() {
let code = SubStatusCode::from_header_value("1002");
assert!(code.is_some());
assert_eq!(code.unwrap().value(), 1002);
}
#[test]
fn from_header_value_with_whitespace() {
let code = SubStatusCode::from_header_value(" 1002 ");
assert!(code.is_some());
assert_eq!(code.unwrap().value(), 1002);
}
#[test]
fn from_header_value_invalid() {
let code = SubStatusCode::from_header_value("not-a-number");
assert!(code.is_none());
}
#[test]
fn from_u32() {
let code = SubStatusCode::from(3200u32);
assert_eq!(code, SubStatusCode::RU_BUDGET_EXCEEDED);
}
#[test]
fn into_u32() {
let value: u32 = SubStatusCode::RU_BUDGET_EXCEEDED.into();
assert_eq!(value, 3200);
}
#[test]
fn display_known_code() {
let code = SubStatusCode::RU_BUDGET_EXCEEDED;
assert_eq!(format!("{}", code), "RUBudgetExceeded (3200)");
}
#[test]
fn display_unknown_code() {
let code = SubStatusCode::new(99999);
assert_eq!(format!("{}", code), "99999");
}
#[test]
fn display_ambiguous_code_without_context() {
let code = SubStatusCode::new(1002);
assert_eq!(format!("{}", code), "1002");
}
#[test]
fn debug_known_code() {
let code = SubStatusCode::RU_BUDGET_EXCEEDED;
assert_eq!(
format!("{:?}", code),
"SubStatusCode::RUBudgetExceeded(3200)"
);
}
#[test]
fn debug_unknown_code() {
let code = SubStatusCode::new(99999);
assert_eq!(format!("{:?}", code), "SubStatusCode(99999)");
}
#[test]
fn debug_ambiguous_code_without_context() {
let code = SubStatusCode::new(1002);
assert_eq!(format!("{:?}", code), "SubStatusCode(1002)");
}
#[test]
fn sub_status_code_equality() {
assert_eq!(
SubStatusCode::new(1002),
SubStatusCode::PARTITION_KEY_RANGE_GONE
);
assert_eq!(
SubStatusCode::new(1002),
SubStatusCode::READ_SESSION_NOT_AVAILABLE
);
assert_ne!(SubStatusCode::new(1002), SubStatusCode::NAME_CACHE_STALE);
}
#[test]
fn default_is_unknown() {
assert_eq!(SubStatusCode::default(), SubStatusCode::UNKNOWN);
assert_eq!(SubStatusCode::default().value(), 0);
}
#[test]
fn name_returns_some_for_unambiguous() {
assert_eq!(
SubStatusCode::RU_BUDGET_EXCEEDED.name(None),
Some("RUBudgetExceeded")
);
}
#[test]
fn name_returns_none_for_unknown() {
assert_eq!(SubStatusCode::new(99999).name(None), None);
}
#[test]
fn name_returns_none_for_ambiguous_without_status() {
assert_eq!(SubStatusCode::new(1002).name(None), None);
}
#[test]
fn name_disambiguates_with_status_code_404() {
let code = SubStatusCode::new(1002);
assert_eq!(
code.name(Some(StatusCode::NotFound)),
Some("ReadSessionNotAvailable")
);
}
#[test]
fn name_disambiguates_with_status_code_410() {
let code = SubStatusCode::new(1002);
assert_eq!(
code.name(Some(StatusCode::Gone)),
Some("PartitionKeyRangeGone")
);
}
#[test]
fn name_1007_disambiguates_410_vs_503() {
let code = SubStatusCode::new(1007);
assert_eq!(code.name(None), None); assert_eq!(
code.name(Some(StatusCode::Gone)),
Some("CompletingSplitOrMerge")
);
assert_eq!(
code.name(Some(StatusCode::ServiceUnavailable)),
Some("InsufficientBindablePartitions")
);
}
#[test]
fn name_1008_disambiguates_403_vs_410() {
let code = SubStatusCode::new(1008);
assert_eq!(code.name(None), None); assert_eq!(
code.name(Some(StatusCode::Forbidden)),
Some("DatabaseAccountNotFound")
);
assert_eq!(
code.name(Some(StatusCode::Gone)),
Some("CompletingPartitionMigration")
);
}
#[test]
fn name_3207_disambiguates_409_vs_429() {
let code = SubStatusCode::new(3207);
assert_eq!(code.name(None), None); assert_eq!(
code.name(Some(StatusCode::Conflict)),
Some("ConfigurationNameAlreadyExists")
);
assert_eq!(
code.name(Some(StatusCode::TooManyRequests)),
Some("PrepareTimeLimitExceeded")
);
}
#[test]
fn serialization() {
let code = SubStatusCode::new(3200);
let json = serde_json::to_string(&code).unwrap();
assert_eq!(json, "3200");
let deserialized: SubStatusCode = serde_json::from_str(&json).unwrap();
assert_eq!(deserialized, code);
}
#[test]
fn sdk_client_codes() {
assert_eq!(SubStatusCode::TRANSPORT_GENERATED_410.value(), 20001);
assert_eq!(SubStatusCode::TIMEOUT_GENERATED_410.value(), 20002);
assert_eq!(SubStatusCode::TRANSPORT_GENERATED_503.value(), 20003);
assert_eq!(SubStatusCode::CLIENT_CPU_OVERLOAD.value(), 20004);
assert_eq!(SubStatusCode::CLIENT_THREAD_STARVATION.value(), 20005);
assert_eq!(SubStatusCode::CLIENT_OPERATION_TIMEOUT.value(), 20008);
}
#[test]
fn sdk_server_codes() {
assert_eq!(
SubStatusCode::NAME_CACHE_STALE_EXCEEDED_RETRY_LIMIT.value(),
21001
);
assert_eq!(
SubStatusCode::PARTITION_KEY_RANGE_GONE_EXCEEDED_RETRY_LIMIT.value(),
21002
);
assert_eq!(SubStatusCode::SERVER_GENERATED_410.value(), 21005);
assert_eq!(
SubStatusCode::GLOBAL_STRONG_WRITE_BARRIER_NOT_MET.value(),
21006
);
assert_eq!(SubStatusCode::READ_QUORUM_NOT_MET.value(), 21007);
assert_eq!(SubStatusCode::SERVER_GENERATED_503.value(), 21008);
}
}