diff --git a/src/bulk/common.ts b/src/bulk/common.ts index 6db513596a..4afb066622 100644 --- a/src/bulk/common.ts +++ b/src/bulk/common.ts @@ -383,6 +383,7 @@ export interface BulkWriteOperationError { index: number; code: number; errmsg: string; + errInfo: Document; op: Document | UpdateStatement | DeleteStatement; } @@ -413,6 +414,11 @@ export class WriteError { return this.err.errmsg; } + /** WriteError details. */ + get errInfo(): Document | undefined { + return this.err.errInfo; + } + /** Returns the underlying operation that caused the error */ getOperation(): Document { return this.err.op; @@ -453,6 +459,7 @@ function mergeBatchResults( index: 0, code: result.code || 0, errmsg: result.message, + errInfo: result.errInfo, op: batch.operations[0] }; @@ -555,6 +562,7 @@ function mergeBatchResults( index: batch.originalIndexes[result.writeErrors[i].index], code: result.writeErrors[i].code, errmsg: result.writeErrors[i].errmsg, + errInfo: result.writeErrors[i].errInfo, op: batch.operations[result.writeErrors[i].index] }; diff --git a/test/functional/bulk.test.js b/test/functional/bulk.test.js index 684e3d8e51..72151081ea 100644 --- a/test/functional/bulk.test.js +++ b/test/functional/bulk.test.js @@ -8,7 +8,7 @@ const { } = require('./shared'); const test = require('./shared').assert; const { MongoDriverError, MongoBatchReExecutionError } = require('../../src/error'); -const { Long } = require('../../src'); +const { Long, MongoBulkWriteError } = require('../../src'); const crypto = require('crypto'); const chai = require('chai'); const expect = chai.expect; @@ -21,6 +21,48 @@ describe('Bulk', function () { return setupDatabase(this.configuration); }); + describe('Write Errors', () => { + describe('errInfo property on insertMany', () => { + let client; + + beforeEach(async function () { + client = this.configuration.newClient({ monitorCommands: true }); + await client.connect(); + }); + + afterEach(async () => { + if (client) { + await client.close(); + } + }); + + it('should be accessible', { + metadata: { requires: { mongodb: '>=5.0.0' } }, + async test() { + try { + await client.db().collection('wc_details').drop(); + } catch { + // don't care + } + + const collection = await client + .db() + .createCollection('wc_details', { validator: { x: { $type: 'string' } } }); + + try { + await collection.insertMany([{ x: /not a string/ }]); + expect.fail('The insert should fail the validation that x must be a string'); + } catch (error) { + expect(error).to.be.instanceOf(MongoBulkWriteError); + expect(error).to.have.property('code', 121); + expect(error).to.have.property('writeErrors').that.is.an('array'); + expect(error.writeErrors[0]).to.have.property('errInfo').that.is.an('object'); + } + } + }); + }); + }); + it('should correctly handle ordered single batch api write command error', { metadata: { requires: { topology: ['single', 'replicaset', 'sharded', 'ssl', 'heap', 'wiredtiger'] }