Skip to content

Commit a493a26

Browse files
authored
Ensure write error is included in exception message (#724)
Implement new CRUD specification prose test for write error details JAVA-3993
1 parent 4e484b0 commit a493a26

File tree

2 files changed

+58
-11
lines changed

2 files changed

+58
-11
lines changed

driver-core/src/main/com/mongodb/MongoWriteException.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public class MongoWriteException extends MongoServerException {
3333
* @param serverAddress the server address
3434
*/
3535
public MongoWriteException(final WriteError error, final ServerAddress serverAddress) {
36-
super(error.getCode(), error.getMessage(), serverAddress);
36+
super("Write operation error on server " + serverAddress + ". Write error: " + error + ". ", serverAddress);
3737
this.error = error;
3838
}
3939

driver-sync/src/test/functional/com/mongodb/client/WriteConcernProseTest.java renamed to driver-sync/src/test/functional/com/mongodb/client/CrudProseTest.java

Lines changed: 57 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,12 @@
1616

1717
package com.mongodb.client;
1818

19+
import com.mongodb.MongoBulkWriteException;
1920
import com.mongodb.MongoWriteConcernException;
21+
import com.mongodb.MongoWriteException;
22+
import com.mongodb.client.model.CreateCollectionOptions;
23+
import com.mongodb.client.model.Filters;
24+
import com.mongodb.client.model.ValidationOptions;
2025
import org.bson.BsonArray;
2126
import org.bson.BsonDocument;
2227
import org.bson.BsonInt32;
@@ -30,41 +35,87 @@
3035
import static java.lang.String.format;
3136
import static java.util.Arrays.asList;
3237
import static org.junit.Assert.assertEquals;
38+
import static org.junit.Assert.assertFalse;
39+
import static org.junit.Assert.assertNotNull;
3340
import static org.junit.Assert.assertTrue;
3441
import static org.junit.Assert.fail;
3542
import static org.junit.Assume.assumeTrue;
3643

37-
// See https://github.com/mongodb/specifications/tree/master/source/change-streams/tests/README.rst#prose-tests
38-
public class WriteConcernProseTest extends DatabaseTestCase {
44+
/**
45+
* See https://github.com/mongodb/specifications/blob/master/source/crud/tests/README.rst#prose-tests
46+
*/
47+
public class CrudProseTest extends DatabaseTestCase {
3948
private BsonDocument failPointDocument;
4049

4150
@Before
4251
@Override
4352
public void setUp() {
44-
assumeTrue(canRunTests());
4553
super.setUp();
4654
}
4755

48-
// Ensure that the WriteConcernError errInfo object is propagated.
56+
/**
57+
* 1. WriteConcernError.details exposes writeConcernError.errInfo
58+
*/
4959
@Test
5060
public void testWriteConcernErrInfoIsPropagated() {
61+
assumeTrue(isDiscoverableReplicaSet() && serverVersionAtLeast(4, 0));
62+
5163
try {
5264
setFailPoint();
5365
collection.insertOne(Document.parse("{ x: 1 }"));
5466
} catch (MongoWriteConcernException e) {
5567
assertEquals(e.getWriteConcernError().getCode(), 100);
56-
assertTrue(e.getWriteConcernError().getCodeName().equals("UnsatisfiableWriteConcern"));
68+
assertEquals("UnsatisfiableWriteConcern", e.getWriteConcernError().getCodeName());
5769
assertEquals(e.getWriteConcernError().getDetails(), new BsonDocument("writeConcern",
5870
new BsonDocument("w", new BsonInt32(2))
5971
.append("wtimeout", new BsonInt32(0))
6072
.append("provenance", new BsonString("clientSupplied"))));
6173
} catch (Exception ex) {
62-
fail(format("Incorrect exception thrown in test: %s" + ex.getClass()));
74+
fail(format("Incorrect exception thrown in test: %s", ex.getClass()));
6375
} finally {
6476
disableFailPoint();
6577
}
6678
}
6779

80+
/**
81+
* 2. WriteError.details exposes writeErrors[].errInfo
82+
*/
83+
@Test
84+
public void testWriteErrorDetailsIsPropagated() {
85+
assumeTrue(serverVersionAtLeast(3, 2));
86+
87+
getCollectionHelper().create(getCollectionName(),
88+
new CreateCollectionOptions()
89+
.validationOptions(new ValidationOptions()
90+
.validator(Filters.type("x", "string"))));
91+
92+
try {
93+
collection.insertOne(new Document("x", 1));
94+
fail("Should throw, as document doesn't match schema");
95+
} catch (MongoWriteException e) {
96+
// These assertions doesn't do exactly what's required by the specification, but it's simpler to implement and nearly as
97+
// effective
98+
assertTrue(e.getMessage().contains("Write error"));
99+
assertNotNull(e.getError().getDetails());
100+
if (serverVersionAtLeast(5, 0)) {
101+
assertFalse(e.getError().getDetails().isEmpty());
102+
}
103+
}
104+
105+
try {
106+
collection.insertMany(asList(new Document("x", 1)));
107+
fail("Should throw, as document doesn't match schema");
108+
} catch (MongoBulkWriteException e) {
109+
// These assertions doesn't do exactly what's required by the specification, but it's simpler to implement and nearly as
110+
// effective
111+
assertTrue(e.getMessage().contains("Write errors"));
112+
assertEquals(1, e.getWriteErrors().size());
113+
if (serverVersionAtLeast(5, 0)) {
114+
assertFalse(e.getWriteErrors().get(0).getDetails().isEmpty());
115+
}
116+
}
117+
}
118+
68119
private void setFailPoint() {
69120
failPointDocument = new BsonDocument("configureFailPoint", new BsonString("failCommand"))
70121
.append("mode", new BsonDocument("times", new BsonInt32(1)))
@@ -81,8 +132,4 @@ private void setFailPoint() {
81132
private void disableFailPoint() {
82133
getCollectionHelper().runAdminCommand(failPointDocument.append("mode", new BsonString("off")));
83134
}
84-
85-
private boolean canRunTests() {
86-
return isDiscoverableReplicaSet() && serverVersionAtLeast(4, 0);
87-
}
88135
}

0 commit comments

Comments
 (0)