From e9025843e43bedb2326675184b6ce49b103e3c77 Mon Sep 17 00:00:00 2001 From: Aditi Khare <106987683+aditi-khare-mongoDB@users.noreply.github.com> Date: Fri, 26 Jul 2024 17:21:00 -0400 Subject: [PATCH] fix(NODE-6276): preserve top level error code MongoWriteConcernError (#4183) --- src/bulk/common.ts | 4 ++-- src/error.ts | 31 ++++++++++++++++++++----------- src/index.ts | 3 ++- test/unit/error.test.ts | 29 +++++++++++++++++++++++++++++ test/unit/index.test.ts | 1 + 5 files changed, 54 insertions(+), 14 deletions(-) diff --git a/src/bulk/common.ts b/src/bulk/common.ts index ad0451e9ac..1a79dd6b1e 100644 --- a/src/bulk/common.ts +++ b/src/bulk/common.ts @@ -616,8 +616,8 @@ function handleMongoWriteConcernError( callback( new MongoBulkWriteError( { - message: err.result?.writeConcernError.errmsg, - code: err.result?.writeConcernError.result + message: err.result.writeConcernError.errmsg, + code: err.result.writeConcernError.code }, new BulkWriteResult(bulkResult, isOrdered) ) diff --git a/src/error.ts b/src/error.ts index 938ce715ff..8ef6c82f55 100644 --- a/src/error.ts +++ b/src/error.ts @@ -1158,6 +1158,23 @@ export class MongoServerSelectionError extends MongoSystemError { } } +/** + * The type of the result property of MongoWriteConcernError + * @public + */ +export interface WriteConcernErrorResult { + writeConcernError: { + code: number; + errmsg: string; + codeName?: string; + errInfo?: Document; + }; + ok: number; + code?: number; + errorLabels?: string[]; + [x: string | number]: unknown; +} + /** * An error thrown when the server reports a writeConcernError * @public @@ -1178,16 +1195,8 @@ export class MongoWriteConcernError extends MongoServerError { * * @public **/ - constructor(result: { - writeConcernError: { - code: number; - errmsg: string; - codeName?: string; - errInfo?: Document; - }; - errorLabels?: string[]; - }) { - super({ ...result, ...result.writeConcernError }); + constructor(result: WriteConcernErrorResult) { + super({ ...result.writeConcernError, ...result }); this.errInfo = result.writeConcernError.errInfo; this.result = result; } @@ -1237,7 +1246,7 @@ export function needsRetryableWriteLabel(error: Error, maxWireVersion: number): } if (error instanceof MongoWriteConcernError) { - return RETRYABLE_WRITE_ERROR_CODES.has(error.result?.code ?? error.code ?? 0); + return RETRYABLE_WRITE_ERROR_CODES.has(error.result.writeConcernError.code ?? error?.code ?? 0); } if (error instanceof MongoError && typeof error.code === 'number') { diff --git a/src/index.ts b/src/index.ts index 8bf6c68617..0ba8f82c01 100644 --- a/src/index.ts +++ b/src/index.ts @@ -73,7 +73,8 @@ export { MongoTopologyClosedError, MongoTransactionError, MongoUnexpectedServerResponseError, - MongoWriteConcernError + MongoWriteConcernError, + WriteConcernErrorResult } from './error'; export { AbstractCursor, diff --git a/test/unit/error.test.ts b/test/unit/error.test.ts index c57ee71da6..6bab40d031 100644 --- a/test/unit/error.test.ts +++ b/test/unit/error.test.ts @@ -740,4 +740,33 @@ describe('MongoErrors', () => { }); }); }); + + describe('MongoWriteConcernError constructor', function () { + context('when no top-level code is provided', function () { + it('error.code is set to writeConcernError.code', function () { + const res = { + writeConcernError: { + code: 81, // nested code + errmsg: 'fake msg' + }, + ok: 1 + }; + expect(new MongoWriteConcernError(res).code).to.equal(81); + }); + }); + context('when top-level code is provided and writeConcernError.code exists', function () { + it('error.code equals the top-level code', function () { + const topLevelCode = 10; + const res = { + writeConcernError: { + code: 81, // nested code + errmsg: 'fake msg' + }, + ok: 1, + code: topLevelCode + }; + expect(new MongoWriteConcernError(res).code).to.equal(topLevelCode); + }); + }); + }); }); diff --git a/test/unit/index.test.ts b/test/unit/index.test.ts index 6509568c01..8dc43c9c74 100644 --- a/test/unit/index.test.ts +++ b/test/unit/index.test.ts @@ -108,6 +108,7 @@ const EXPECTED_EXPORTS = [ 'MongoTransactionError', 'MongoUnexpectedServerResponseError', 'MongoWriteConcernError', + 'WriteConcernErrorResult', 'ObjectId', 'OrderedBulkOperation', 'ProfilingLevel',