-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Fix MixedBulkWriteOperation
such that it does not leak MongoWriteConcernWithResponseException
to users
#1051
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
driver-sync/src/test/functional/com/mongodb/client/RetryableWritesProseTest.java
Show resolved
Hide resolved
assertThrows(MongoWriteConcernException.class, () -> { | ||
try { | ||
collection.insertOne(new Document()); | ||
} catch (MongoWriteConcernException e) { | ||
assertEquals(91, e.getCode()); | ||
throw e; | ||
} | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that the leak is fixed, we can expect MongoWriteConcernException
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI this can also be written as:
MongoWriteConcernException e = assertThrows(MongoWriteConcernException.class, () -> collection.insertOne(new Document()));
assertEquals(91, e.getCode());
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, I have not realized assertThrows
returns the thrown exception :) Done.
driver-core/src/main/com/mongodb/internal/operation/MixedBulkWriteOperation.java
Show resolved
Hide resolved
@@ -292,9 +271,10 @@ private BulkWriteResult executeBulkWriteBatch(final RetryState retryState, final | |||
currentBulkWriteTracker = BulkWriteTracker.attachNext(retryState, currentBatch); | |||
currentBatch = currentBulkWriteTracker.batch().orElseThrow(Assertions::fail); | |||
} catch (MongoException exception) { | |||
if (!(retryState.isFirstAttempt() || (exception instanceof MongoWriteConcernWithResponseException))) { | |||
if (!retryState.isFirstAttempt() && !(exception instanceof MongoWriteConcernWithResponseException)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed this because I found the new form easier to understand (I was trying to understand what's going on, not very successfully, though).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should there be a separate catch for MongoWriteConcernWithResponseException
to make this easier to understand?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently we have
} catch (MongoException exception) {
if (!retryState.isFirstAttempt() && !(exception instanceof MongoWriteConcernWithResponseException)) {
addRetryableWriteErrorLabel(exception, maxWireVersion);
}
handleMongoWriteConcernWithResponseException(retryState, false);
throw exception;
}
with the change you propose we will have
} catch (MongoWriteConcernWithResponseException exception) {
handleMongoWriteConcernWithResponseException(retryState, false);
throw exception;
} catch (MongoException exception) {
if (!retryState.isFirstAttempt()) {
addRetryableWriteErrorLabel(exception, maxWireVersion);
}
handleMongoWriteConcernWithResponseException(retryState, false);
throw exception;
}
The current code is shorter and does not have code duplication, the proposed code does not have the instanceof
check. To me the current approach seems the lesser of two evils.
driver-core/src/main/com/mongodb/internal/operation/MixedBulkWriteOperation.java
Show resolved
Hide resolved
…ernWithResponseException to users JAVA-4775
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good - added a couple of comments for consideration only
assertThrows(MongoWriteConcernException.class, () -> { | ||
try { | ||
collection.insertOne(new Document()); | ||
} catch (MongoWriteConcernException e) { | ||
assertEquals(91, e.getCode()); | ||
throw e; | ||
} | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI this can also be written as:
MongoWriteConcernException e = assertThrows(MongoWriteConcernException.class, () -> collection.insertOne(new Document()));
assertEquals(91, e.getCode());
@@ -292,9 +271,10 @@ private BulkWriteResult executeBulkWriteBatch(final RetryState retryState, final | |||
currentBulkWriteTracker = BulkWriteTracker.attachNext(retryState, currentBatch); | |||
currentBatch = currentBulkWriteTracker.batch().orElseThrow(Assertions::fail); | |||
} catch (MongoException exception) { | |||
if (!(retryState.isFirstAttempt() || (exception instanceof MongoWriteConcernWithResponseException))) { | |||
if (!retryState.isFirstAttempt() && !(exception instanceof MongoWriteConcernWithResponseException)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should there be a separate catch for MongoWriteConcernWithResponseException
to make this easier to understand?
...-sync/src/test/functional/com/mongodb/client/MongoWriteConcernWithResponseExceptionTest.java
Show resolved
Hide resolved
driver-core/src/main/com/mongodb/internal/operation/MixedBulkWriteOperation.java
Show resolved
Hide resolved
driver-sync/src/test/functional/com/mongodb/client/RetryableWritesProseTest.java
Outdated
Show resolved
Hide resolved
...-sync/src/test/functional/com/mongodb/client/MongoWriteConcernWithResponseExceptionTest.java
Show resolved
Hide resolved
MongoCollection<Document> collection = client.getDatabase(getDefaultDatabaseName()) | ||
.getCollection("originalErrorMustBePropagatedIfNoWritesPerformed"); | ||
collection.drop(); | ||
assertThrows(MongoWriteConcernException.class, () -> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assertThrows(MongoWriteConcernException.class, () -> { | |
assertThrows(MongoWriteConcernException.class, () -> collection.insertOne(new Document())); |
If it's asserting that it throws MongoWriteConcernException
it can't also throw MongoWriteConcernWithResponseException
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assertThrows(MongoWriteConcernException.class, ...)
verifies that MongoWriteConcernException
is thrown. What if a different exception is thrown? - it simply reports that. I want to have the The internal exception leaked
message when the different exception is MongoWriteConcernWithResponseException
, and I don't see another way of achieving this. Of course, if this happens, both assertions will fail with the inner assertion being the cause of the outer one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems overly complicated structure just to get a more helpful failure message, but I can live with it.
Co-authored-by: Jeff Yemin <[email protected]>
JAVA-4775