Skip to content

Commit 623b5fc

Browse files
fix(NODE-6276): preserve top level error code MongoWriteConcernError
1 parent 357ca08 commit 623b5fc

File tree

4 files changed

+58
-17
lines changed

4 files changed

+58
-17
lines changed

src/bulk/common.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -616,8 +616,8 @@ function handleMongoWriteConcernError(
616616
callback(
617617
new MongoBulkWriteError(
618618
{
619-
message: err.result?.writeConcernError.errmsg,
620-
code: err.result?.writeConcernError.result
619+
message: err?.result.writeConcernError.errmsg,
620+
code: err?.result.writeConcernError.code
621621
},
622622
new BulkWriteResult(bulkResult, isOrdered)
623623
)

src/error.ts

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,14 +1158,30 @@ export class MongoServerSelectionError extends MongoSystemError {
11581158
}
11591159
}
11601160

1161+
/**
1162+
* The type of the result property of MongoWriteConcernError
1163+
* @public
1164+
*/
1165+
export interface WriteConcernErrorResult {
1166+
writeConcernError: {
1167+
code: number;
1168+
errmsg: string;
1169+
codeName?: string;
1170+
errInfo?: Document;
1171+
};
1172+
ok: 0 | 1;
1173+
code?: number;
1174+
[x: string | number]: unknown;
1175+
}
1176+
11611177
/**
11621178
* An error thrown when the server reports a writeConcernError
11631179
* @public
11641180
* @category Error
11651181
*/
11661182
export class MongoWriteConcernError extends MongoServerError {
11671183
/** The result document */
1168-
result: Document;
1184+
result: WriteConcernErrorResult;
11691185

11701186
/**
11711187
* **Do not use this constructor!**
@@ -1178,18 +1194,11 @@ export class MongoWriteConcernError extends MongoServerError {
11781194
*
11791195
* @public
11801196
**/
1181-
constructor(result: {
1182-
writeConcernError: {
1183-
code: number;
1184-
errmsg: string;
1185-
codeName?: string;
1186-
errInfo?: Document;
1187-
};
1188-
errorLabels?: string[];
1189-
}) {
1190-
super({ ...result, ...result.writeConcernError });
1191-
this.errInfo = result.writeConcernError.errInfo;
1197+
constructor(result: WriteConcernErrorResult) {
1198+
super(result);
1199+
this.errInfo = result.writeConcernError?.errInfo;
11921200
this.result = result;
1201+
this.code = result.code ? result.code : undefined;
11931202
}
11941203

11951204
override get name(): string {
@@ -1237,7 +1246,9 @@ export function needsRetryableWriteLabel(error: Error, maxWireVersion: number):
12371246
}
12381247

12391248
if (error instanceof MongoWriteConcernError) {
1240-
return RETRYABLE_WRITE_ERROR_CODES.has(error.result?.code ?? error.code ?? 0);
1249+
return RETRYABLE_WRITE_ERROR_CODES.has(
1250+
error.result.writeConcernError?.code ?? error?.code ?? 0
1251+
);
12411252
}
12421253

12431254
if (error instanceof MongoError && typeof error.code === 'number') {

test/unit/error.test.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ import {
3030
setDifference,
3131
type TopologyDescription,
3232
type TopologyOptions,
33-
WaitQueueTimeoutError as MongoWaitQueueTimeoutError
33+
WaitQueueTimeoutError as MongoWaitQueueTimeoutError,
34+
WriteConcernErrorResult
3435
} from '../mongodb';
3536
import { ReplSetFixture } from '../tools/common';
3637
import { cleanup } from '../tools/mongodb-mock/index';
@@ -740,4 +741,33 @@ describe('MongoErrors', () => {
740741
});
741742
});
742743
});
744+
745+
describe('MongoWriteConcernError constructor', function () {
746+
context('when no top-level code is provided and writeConcernError.code exists', function () {
747+
it('error.code remains undefined', function () {
748+
const res: WriteConcernErrorResult = {
749+
writeConcernError: {
750+
code: 81, // nested code
751+
errmsg: 'fake msg'
752+
},
753+
ok: 1
754+
};
755+
expect(new MongoWriteConcernError(res).code).to.equal(undefined);
756+
});
757+
});
758+
context('when top-level code is provided and writeConcernError.code exists', function () {
759+
it('error.code equals the top-level code', function () {
760+
const topLevelCode = 10;
761+
const res: WriteConcernErrorResult = {
762+
writeConcernError: {
763+
code: 81, // nested code
764+
errmsg: 'fake msg'
765+
},
766+
ok: 1,
767+
code: topLevelCode
768+
};
769+
expect(new MongoWriteConcernError(res).code).to.equal(topLevelCode);
770+
});
771+
});
772+
});
743773
});

test/unit/mongo_client.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -737,7 +737,7 @@ describe('MongoClient', function () {
737737
expect(error).to.have.property('code', 'EBADNAME');
738738
});
739739

740-
it('srvServiceName should not error if it is greater than 15 characters as long as the DNS query limit is not surpassed', async () => {
740+
it.only('srvServiceName should not error if it is greater than 15 characters as long as the DNS query limit is not surpassed', async () => {
741741
const options = parseOptions('mongodb+srv://localhost.a.com', {
742742
srvServiceName: 'a'.repeat(16)
743743
});

0 commit comments

Comments
 (0)