Skip to content

Commit c023242

Browse files
feat(NODE-5988): Provide access to raw results doc on MongoServerError (#4016)
1 parent 69de253 commit c023242

26 files changed

+1234
-7
lines changed

src/error.ts

+11-1
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,8 @@ export class MongoError extends Error {
200200
* @category Error
201201
*/
202202
export class MongoServerError extends MongoError {
203+
/** Raw error result document returned by server. */
204+
errorResponse: ErrorDescription;
203205
codeName?: string;
204206
writeConcernError?: Document;
205207
errInfo?: Document;
@@ -223,9 +225,17 @@ export class MongoServerError extends MongoError {
223225
this[kErrorLabels] = new Set(message.errorLabels);
224226
}
225227

228+
this.errorResponse = message;
229+
226230
for (const name in message) {
227-
if (name !== 'errorLabels' && name !== 'errmsg' && name !== 'message')
231+
if (
232+
name !== 'errorLabels' &&
233+
name !== 'errmsg' &&
234+
name !== 'message' &&
235+
name !== 'errorResponse'
236+
) {
228237
this[name] = message[name];
238+
}
229239
}
230240
}
231241

src/sdam/server.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ export class Server extends TypedEventEmitter<ServerEvents> {
171171
this.monitor.on(event, (e: any) => this.emit(event, e));
172172
}
173173

174-
this.monitor.on('resetServer', (error: MongoError) => markServerUnknown(this, error));
174+
this.monitor.on('resetServer', (error: MongoServerError) => markServerUnknown(this, error));
175175
this.monitor.on(Server.SERVER_HEARTBEAT_SUCCEEDED, (event: ServerHeartbeatSucceededEvent) => {
176176
this.emit(
177177
Server.DESCRIPTION_RECEIVED,
@@ -369,7 +369,7 @@ export class Server extends TypedEventEmitter<ServerEvents> {
369369
// clear for the specific service id.
370370
if (!this.loadBalanced) {
371371
error.addErrorLabel(MongoErrorLabel.ResetPool);
372-
markServerUnknown(this, error);
372+
markServerUnknown(this, error as MongoServerError);
373373
} else if (connection) {
374374
this.pool.clear({ serviceId: connection.serviceId });
375375
}
@@ -385,7 +385,7 @@ export class Server extends TypedEventEmitter<ServerEvents> {
385385
if (shouldClearPool) {
386386
error.addErrorLabel(MongoErrorLabel.ResetPool);
387387
}
388-
markServerUnknown(this, error);
388+
markServerUnknown(this, error as MongoServerError);
389389
process.nextTick(() => this.requestCheck());
390390
}
391391
}

src/sdam/topology_description.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ export class TopologyDescription {
313313
);
314314

315315
if (descriptionsWithError.length > 0) {
316-
return descriptionsWithError[0].error;
316+
return descriptionsWithError[0].error as MongoServerError;
317317
}
318318

319319
return null;

test/integration/collection-management/collection_management.spec.test.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ const { loadSpecTests } = require('../../spec/index');
44
const { runUnifiedSuite } = require('../../tools/unified-spec-runner/runner');
55

66
// The Node driver does not have a Collection.modifyCollection helper.
7-
const SKIPPED_TESTS = ['modifyCollection to changeStreamPreAndPostImages enabled'];
7+
const SKIPPED_TESTS = [
8+
'modifyCollection to changeStreamPreAndPostImages enabled',
9+
'modifyCollection prepareUnique violations are accessible'
10+
];
811

912
describe('Collection management unified spec tests', function () {
1013
runUnifiedSuite(loadSpecTests('collection-management'), ({ description }) =>

test/integration/crud/crud.spec.test.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,10 @@ describe('CRUD spec v1', function () {
425425
}
426426
});
427427

428+
// TODO(NODE-5998) - The Node driver UTR does not have a Collection.modifyCollection helper.
429+
const SKIPPED_TESTS = ['findOneAndUpdate document validation errInfo is accessible'];
428430
describe('CRUD unified', function () {
429-
runUnifiedSuite(loadSpecTests(path.join('crud', 'unified')));
431+
runUnifiedSuite(loadSpecTests(path.join('crud', 'unified')), ({ description }) =>
432+
SKIPPED_TESTS.includes(description) ? `the Node driver does not have a collMod helper.` : false
433+
);
430434
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
{
2+
"description": "modifyCollection-errorResponse",
3+
"schemaVersion": "1.12",
4+
"createEntities": [
5+
{
6+
"client": {
7+
"id": "client0",
8+
"observeEvents": [
9+
"commandStartedEvent"
10+
]
11+
}
12+
},
13+
{
14+
"database": {
15+
"id": "database0",
16+
"client": "client0",
17+
"databaseName": "collMod-tests"
18+
}
19+
},
20+
{
21+
"collection": {
22+
"id": "collection0",
23+
"database": "database0",
24+
"collectionName": "test"
25+
}
26+
}
27+
],
28+
"initialData": [
29+
{
30+
"collectionName": "test",
31+
"databaseName": "collMod-tests",
32+
"documents": [
33+
{
34+
"_id": 1,
35+
"x": 1
36+
},
37+
{
38+
"_id": 2,
39+
"x": 1
40+
}
41+
]
42+
}
43+
],
44+
"tests": [
45+
{
46+
"description": "modifyCollection prepareUnique violations are accessible",
47+
"runOnRequirements": [
48+
{
49+
"minServerVersion": "5.2"
50+
}
51+
],
52+
"operations": [
53+
{
54+
"name": "createIndex",
55+
"object": "collection0",
56+
"arguments": {
57+
"keys": {
58+
"x": 1
59+
}
60+
}
61+
},
62+
{
63+
"name": "modifyCollection",
64+
"object": "database0",
65+
"arguments": {
66+
"collection": "test",
67+
"index": {
68+
"keyPattern": {
69+
"x": 1
70+
},
71+
"prepareUnique": true
72+
}
73+
}
74+
},
75+
{
76+
"name": "insertOne",
77+
"object": "collection0",
78+
"arguments": {
79+
"document": {
80+
"_id": 3,
81+
"x": 1
82+
}
83+
},
84+
"expectError": {
85+
"errorCode": 11000
86+
}
87+
},
88+
{
89+
"name": "modifyCollection",
90+
"object": "database0",
91+
"arguments": {
92+
"collection": "test",
93+
"index": {
94+
"keyPattern": {
95+
"x": 1
96+
},
97+
"unique": true
98+
}
99+
},
100+
"expectError": {
101+
"isClientError": false,
102+
"errorCode": 359,
103+
"errorResponse": {
104+
"violations": [
105+
{
106+
"ids": [
107+
1,
108+
2
109+
]
110+
}
111+
]
112+
}
113+
}
114+
}
115+
]
116+
}
117+
]
118+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
description: "modifyCollection-errorResponse"
2+
3+
schemaVersion: "1.12"
4+
5+
createEntities:
6+
- client:
7+
id: &client0 client0
8+
observeEvents: [ commandStartedEvent ]
9+
- database:
10+
id: &database0 database0
11+
client: *client0
12+
databaseName: &database0Name collMod-tests
13+
- collection:
14+
id: &collection0 collection0
15+
database: *database0
16+
collectionName: &collection0Name test
17+
18+
initialData: &initialData
19+
- collectionName: *collection0Name
20+
databaseName: *database0Name
21+
documents:
22+
- { _id: 1, x: 1 }
23+
- { _id: 2, x: 1 }
24+
25+
tests:
26+
- description: "modifyCollection prepareUnique violations are accessible"
27+
runOnRequirements:
28+
- minServerVersion: "5.2" # SERVER-61158
29+
operations:
30+
- name: createIndex
31+
object: *collection0
32+
arguments:
33+
keys: { x: 1 }
34+
- name: modifyCollection
35+
object: *database0
36+
arguments:
37+
collection: *collection0Name
38+
index:
39+
keyPattern: { x: 1 }
40+
prepareUnique: true
41+
- name: insertOne
42+
object: *collection0
43+
arguments:
44+
document: { _id: 3, x: 1 }
45+
expectError:
46+
errorCode: 11000 # DuplicateKey
47+
- name: modifyCollection
48+
object: *database0
49+
arguments:
50+
collection: *collection0Name
51+
index:
52+
keyPattern: { x: 1 }
53+
unique: true
54+
expectError:
55+
isClientError: false
56+
errorCode: 359 # CannotConvertIndexToUnique
57+
errorResponse:
58+
violations:
59+
- { ids: [ 1, 2 ] }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
{
2+
"description": "aggregate-merge-errorResponse",
3+
"schemaVersion": "1.12",
4+
"createEntities": [
5+
{
6+
"client": {
7+
"id": "client0"
8+
}
9+
},
10+
{
11+
"database": {
12+
"id": "database0",
13+
"client": "client0",
14+
"databaseName": "crud-tests"
15+
}
16+
},
17+
{
18+
"collection": {
19+
"id": "collection0",
20+
"database": "database0",
21+
"collectionName": "test"
22+
}
23+
}
24+
],
25+
"initialData": [
26+
{
27+
"collectionName": "test",
28+
"databaseName": "crud-tests",
29+
"documents": [
30+
{
31+
"_id": 1,
32+
"x": 1
33+
},
34+
{
35+
"_id": 2,
36+
"x": 1
37+
}
38+
]
39+
}
40+
],
41+
"tests": [
42+
{
43+
"description": "aggregate $merge DuplicateKey error is accessible",
44+
"runOnRequirements": [
45+
{
46+
"minServerVersion": "5.1",
47+
"topologies": [
48+
"single",
49+
"replicaset"
50+
]
51+
}
52+
],
53+
"operations": [
54+
{
55+
"name": "aggregate",
56+
"object": "database0",
57+
"arguments": {
58+
"pipeline": [
59+
{
60+
"$documents": [
61+
{
62+
"_id": 2,
63+
"x": 1
64+
}
65+
]
66+
},
67+
{
68+
"$merge": {
69+
"into": "test",
70+
"whenMatched": "fail"
71+
}
72+
}
73+
]
74+
},
75+
"expectError": {
76+
"errorCode": 11000,
77+
"errorResponse": {
78+
"keyPattern": {
79+
"_id": 1
80+
},
81+
"keyValue": {
82+
"_id": 2
83+
}
84+
}
85+
}
86+
}
87+
]
88+
}
89+
]
90+
}

0 commit comments

Comments
 (0)