11import type { Document } from './bson' ;
2+ import type { ServerType } from './sdam/common' ;
23import type { TopologyVersion } from './sdam/server_description' ;
34import type { TopologyDescription } from './sdam/topology_description' ;
45
@@ -1167,6 +1168,23 @@ export class MongoServerSelectionError extends MongoSystemError {
11671168 }
11681169}
11691170
1171+ /**
1172+ * The type of the result property of MongoWriteConcernError
1173+ * @public
1174+ */
1175+ export interface WriteConcernErrorResult {
1176+ writeConcernError : {
1177+ code : number ;
1178+ errmsg : string ;
1179+ codeName ?: string ;
1180+ errInfo ?: Document ;
1181+ } ;
1182+ ok : number ;
1183+ code ?: number ;
1184+ errorLabels ?: string [ ] ;
1185+ [ x : string | number ] : unknown ;
1186+ }
1187+
11701188/**
11711189 * An error thrown when the server reports a writeConcernError
11721190 * @public
@@ -1187,16 +1205,8 @@ export class MongoWriteConcernError extends MongoServerError {
11871205 *
11881206 * @public
11891207 **/
1190- constructor ( result : {
1191- writeConcernError : {
1192- code : number ;
1193- errmsg : string ;
1194- codeName ?: string ;
1195- errInfo ?: Document ;
1196- } ;
1197- errorLabels ?: string [ ] ;
1198- } ) {
1199- super ( { ...result , ...result . writeConcernError } ) ;
1208+ constructor ( result : WriteConcernErrorResult ) {
1209+ super ( { ...result . writeConcernError , ...result } ) ;
12001210 this . errInfo = result . writeConcernError . errInfo ;
12011211 this . result = result ;
12021212 }
@@ -1226,7 +1236,11 @@ const RETRYABLE_READ_ERROR_CODES = new Set<number>([
12261236// see: https://github.com/mongodb/specifications/blob/master/source/retryable-writes/retryable-writes.rst#terms
12271237const RETRYABLE_WRITE_ERROR_CODES = RETRYABLE_READ_ERROR_CODES ;
12281238
1229- export function needsRetryableWriteLabel ( error : Error , maxWireVersion : number ) : boolean {
1239+ export function needsRetryableWriteLabel (
1240+ error : Error ,
1241+ maxWireVersion : number ,
1242+ serverType : ServerType
1243+ ) : boolean {
12301244 // pre-4.4 server, then the driver adds an error label for every valid case
12311245 // execute operation will only inspect the label, code/message logic is handled here
12321246 if ( error instanceof MongoNetworkError ) {
@@ -1246,11 +1260,17 @@ export function needsRetryableWriteLabel(error: Error, maxWireVersion: number):
12461260 }
12471261
12481262 if ( error instanceof MongoWriteConcernError ) {
1249- return RETRYABLE_WRITE_ERROR_CODES . has ( error . result ?. code ?? error . code ?? 0 ) ;
1263+ if ( serverType === 'Mongos' && maxWireVersion < 9 ) {
1264+ // use original top-level code from server response
1265+ return RETRYABLE_WRITE_ERROR_CODES . has ( error . result . code ?? 0 ) ;
1266+ }
1267+ return RETRYABLE_WRITE_ERROR_CODES . has (
1268+ error . result . writeConcernError . code ?? Number ( error . code ) ?? 0
1269+ ) ;
12501270 }
12511271
1252- if ( error instanceof MongoError && typeof error . code === 'number' ) {
1253- return RETRYABLE_WRITE_ERROR_CODES . has ( error . code ) ;
1272+ if ( error instanceof MongoError ) {
1273+ return RETRYABLE_WRITE_ERROR_CODES . has ( Number ( error . code ) ) ;
12541274 }
12551275
12561276 const isNotWritablePrimaryError = LEGACY_NOT_WRITABLE_PRIMARY_ERROR_MESSAGE . test ( error . message ) ;
0 commit comments