diff --git a/driver-core/src/main/com/mongodb/MongoServerException.java b/driver-core/src/main/com/mongodb/MongoServerException.java index a981dc1c92..12ba91372c 100644 --- a/driver-core/src/main/com/mongodb/MongoServerException.java +++ b/driver-core/src/main/com/mongodb/MongoServerException.java @@ -71,6 +71,21 @@ public MongoServerException(final int code, @Nullable final String errorCodeName this.serverAddress = serverAddress; } + /** + * Construct a new instance. + * + * @param code the error code from the server + * @param message the message from the server + * @param t the throwable cause + * @param serverAddress the address of the server + * @since 5.7 + */ + public MongoServerException(final int code, final String message, final Throwable t, final ServerAddress serverAddress) { + super(code, message, t); + this.errorCodeName = null; + this.serverAddress = serverAddress; + } + /** * Gets the address of the server. * diff --git a/driver-core/src/main/com/mongodb/MongoWriteConcernException.java b/driver-core/src/main/com/mongodb/MongoWriteConcernException.java index 77aca03e02..9ce38660a0 100644 --- a/driver-core/src/main/com/mongodb/MongoWriteConcernException.java +++ b/driver-core/src/main/com/mongodb/MongoWriteConcernException.java @@ -76,9 +76,27 @@ public MongoWriteConcernException(final WriteConcernError writeConcernError, @Nu */ public MongoWriteConcernException(final WriteConcernError writeConcernError, @Nullable final WriteConcernResult writeConcernResult, final ServerAddress serverAddress, final Collection errorLabels) { - super(writeConcernError.getCode(), writeConcernError.getMessage(), serverAddress); + super(notNull("writeConcernError", writeConcernError).getCode(), writeConcernError.getMessage(), serverAddress); this.writeConcernResult = writeConcernResult; - this.writeConcernError = notNull("writeConcernError", writeConcernError); + this.writeConcernError = writeConcernError; + addLabels(errorLabels); + } + + /** + * Construct an instance. + * + * @param writeConcernError the non-null write concern error + * @param writeConcernResult the write result + * @param serverAddress the non-null server address + * @param errorLabels the server errorLabels + * @param t the throwable cause + * @since 5.7 + */ + public MongoWriteConcernException(final WriteConcernError writeConcernError, @Nullable final WriteConcernResult writeConcernResult, + final ServerAddress serverAddress, final Collection errorLabels, final Throwable t) { + super(notNull("writeConcernError", writeConcernError).getCode(), writeConcernError.getMessage(), t, serverAddress); + this.writeConcernResult = writeConcernResult; + this.writeConcernError = writeConcernError; addLabels(errorLabels); } diff --git a/driver-core/src/main/com/mongodb/internal/operation/MongoBulkWriteExceptionHelper.java b/driver-core/src/main/com/mongodb/internal/operation/MongoBulkWriteExceptionHelper.java new file mode 100644 index 0000000000..81bf43e1f7 --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/operation/MongoBulkWriteExceptionHelper.java @@ -0,0 +1,72 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.mongodb.internal.operation; + +import com.mongodb.MongoBulkWriteException; +import com.mongodb.MongoException; +import com.mongodb.MongoInternalException; +import com.mongodb.MongoWriteConcernException; +import com.mongodb.MongoWriteException; +import com.mongodb.WriteConcernResult; +import com.mongodb.WriteError; +import com.mongodb.bulk.BulkWriteResult; +import com.mongodb.bulk.WriteConcernError; +import com.mongodb.internal.bulk.WriteRequest; +import org.bson.BsonDocument; + +/** + *

This class is not part of the public API and may be removed or changed at any time

+ */ +public final class MongoBulkWriteExceptionHelper { + + public static MongoException translateSingleOperationBulkWriteResultException( + final WriteRequest.Type type, final MongoBulkWriteException e) { + MongoException exception; + WriteConcernError writeConcernError = e.getWriteConcernError(); + if (writeConcernError != null) { + exception = new MongoWriteConcernException(writeConcernError, + translateBulkWriteResult(type, e.getWriteResult()), e.getServerAddress(), e.getErrorLabels(), e); + } else if (!e.getWriteErrors().isEmpty()) { + exception = new MongoWriteException(new WriteError(e.getWriteErrors().get(0)), e.getServerAddress(), + e.getErrorLabels()); + } else { + exception = new MongoWriteException(new WriteError(-1, "Unknown write error", new BsonDocument()), + e.getServerAddress(), e.getErrorLabels()); + } + return exception; + } + + private static WriteConcernResult translateBulkWriteResult(final WriteRequest.Type type, final BulkWriteResult writeResult) { + switch (type) { + case INSERT: + return WriteConcernResult.acknowledged(writeResult.getInsertedCount(), false, null); + case DELETE: + return WriteConcernResult.acknowledged(writeResult.getDeletedCount(), false, null); + case UPDATE: + case REPLACE: + return WriteConcernResult.acknowledged(writeResult.getMatchedCount() + writeResult.getUpserts().size(), + writeResult.getMatchedCount() > 0, + writeResult.getUpserts().isEmpty() + ? null : writeResult.getUpserts().get(0).getId()); + default: + throw new MongoInternalException("Unhandled write request type: " + type); + } + } + + + private MongoBulkWriteExceptionHelper() { + } +} diff --git a/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/internal/MongoOperationPublisher.java b/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/internal/MongoOperationPublisher.java index 84c810f1b5..ebba5349c7 100644 --- a/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/internal/MongoOperationPublisher.java +++ b/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/internal/MongoOperationPublisher.java @@ -18,17 +18,11 @@ import com.mongodb.AutoEncryptionSettings; import com.mongodb.MongoBulkWriteException; import com.mongodb.MongoClientException; -import com.mongodb.MongoException; import com.mongodb.MongoNamespace; -import com.mongodb.MongoWriteConcernException; -import com.mongodb.MongoWriteException; import com.mongodb.ReadConcern; import com.mongodb.ReadPreference; import com.mongodb.WriteConcern; -import com.mongodb.WriteConcernResult; -import com.mongodb.WriteError; import com.mongodb.bulk.BulkWriteResult; -import com.mongodb.bulk.WriteConcernError; import com.mongodb.client.model.BulkWriteOptions; import com.mongodb.client.model.CountOptions; import com.mongodb.client.model.CreateCollectionOptions; @@ -66,7 +60,6 @@ import com.mongodb.internal.operation.WriteOperation; import com.mongodb.lang.Nullable; import com.mongodb.reactivestreams.client.ClientSession; -import org.bson.BsonDocument; import org.bson.BsonValue; import org.bson.UuidRepresentation; import org.bson.codecs.configuration.CodecRegistry; @@ -86,6 +79,7 @@ import static com.mongodb.assertions.Assertions.assertNotNull; import static com.mongodb.assertions.Assertions.isTrue; import static com.mongodb.assertions.Assertions.notNull; +import static com.mongodb.internal.operation.MongoBulkWriteExceptionHelper.translateSingleOperationBulkWriteResultException; import static java.util.Collections.singletonList; import static org.bson.codecs.configuration.CodecRegistries.withUuidRepresentation; @@ -530,34 +524,7 @@ private Mono createSingleWriteRequestMono( @Nullable final ClientSession clientSession, final WriteRequest.Type type) { return createWriteOperationMono(operations::getTimeoutSettings, operation, clientSession) - .onErrorMap(MongoBulkWriteException.class, e -> { - MongoException exception; - WriteConcernError writeConcernError = e.getWriteConcernError(); - if (e.getWriteErrors().isEmpty() && writeConcernError != null) { - WriteConcernResult writeConcernResult; - if (type == WriteRequest.Type.INSERT) { - writeConcernResult = WriteConcernResult.acknowledged(e.getWriteResult().getInsertedCount(), false, null); - } else if (type == WriteRequest.Type.DELETE) { - writeConcernResult = WriteConcernResult.acknowledged(e.getWriteResult().getDeletedCount(), false, null); - } else { - writeConcernResult = WriteConcernResult - .acknowledged(e.getWriteResult().getMatchedCount() + e.getWriteResult().getUpserts().size(), - e.getWriteResult().getMatchedCount() > 0, - e.getWriteResult().getUpserts().isEmpty() - ? null : e.getWriteResult().getUpserts().get(0).getId()); - } - exception = new MongoWriteConcernException(writeConcernError, writeConcernResult, e.getServerAddress(), - e.getErrorLabels()); - } else if (!e.getWriteErrors().isEmpty()) { - exception = new MongoWriteException(new WriteError(e.getWriteErrors().get(0)), e.getServerAddress(), - e.getErrorLabels()); - } else { - exception = new MongoWriteException(new WriteError(-1, "Unknown write error", new BsonDocument()), - e.getServerAddress(), e.getErrorLabels()); - } - - return exception; - }); + .onErrorMap(MongoBulkWriteException.class, e -> translateSingleOperationBulkWriteResultException(type, e)); } private OperationExecutor getExecutor(final TimeoutSettings timeoutSettings) { diff --git a/driver-sync/src/main/com/mongodb/client/internal/MongoCollectionImpl.java b/driver-sync/src/main/com/mongodb/client/internal/MongoCollectionImpl.java index 736e154121..1a730ca461 100755 --- a/driver-sync/src/main/com/mongodb/client/internal/MongoCollectionImpl.java +++ b/driver-sync/src/main/com/mongodb/client/internal/MongoCollectionImpl.java @@ -18,15 +18,10 @@ import com.mongodb.AutoEncryptionSettings; import com.mongodb.MongoBulkWriteException; -import com.mongodb.MongoInternalException; import com.mongodb.MongoNamespace; -import com.mongodb.MongoWriteConcernException; -import com.mongodb.MongoWriteException; import com.mongodb.ReadConcern; import com.mongodb.ReadPreference; import com.mongodb.WriteConcern; -import com.mongodb.WriteConcernResult; -import com.mongodb.WriteError; import com.mongodb.bulk.BulkWriteResult; import com.mongodb.client.AggregateIterable; import com.mongodb.client.ChangeStreamIterable; @@ -85,6 +80,7 @@ import static com.mongodb.internal.bulk.WriteRequest.Type.INSERT; import static com.mongodb.internal.bulk.WriteRequest.Type.REPLACE; import static com.mongodb.internal.bulk.WriteRequest.Type.UPDATE; +import static com.mongodb.internal.operation.MongoBulkWriteExceptionHelper.translateSingleOperationBulkWriteResultException; import static java.util.Collections.singletonList; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static org.bson.codecs.configuration.CodecRegistries.withUuidRepresentation; @@ -1113,34 +1109,9 @@ private BulkWriteResult executeSingleWriteRequest(@Nullable final ClientSession final WriteOperation writeOperation, final WriteRequest.Type type) { try { - return getExecutor(timeoutSettings) - .execute(writeOperation, readConcern, clientSession); + return getExecutor(timeoutSettings).execute(writeOperation, readConcern, clientSession); } catch (MongoBulkWriteException e) { - if (e.getWriteErrors().isEmpty()) { - throw new MongoWriteConcernException(e.getWriteConcernError(), - translateBulkWriteResult(type, e.getWriteResult()), - e.getServerAddress(), e.getErrorLabels()); - } else { - throw new MongoWriteException(new WriteError(e.getWriteErrors().get(0)), e.getServerAddress(), e.getErrorLabels()); - } - - } - } - - private WriteConcernResult translateBulkWriteResult(final WriteRequest.Type type, final BulkWriteResult writeResult) { - switch (type) { - case INSERT: - return WriteConcernResult.acknowledged(writeResult.getInsertedCount(), false, null); - case DELETE: - return WriteConcernResult.acknowledged(writeResult.getDeletedCount(), false, null); - case UPDATE: - case REPLACE: - return WriteConcernResult.acknowledged(writeResult.getMatchedCount() + writeResult.getUpserts().size(), - writeResult.getMatchedCount() > 0, - writeResult.getUpserts().isEmpty() - ? null : writeResult.getUpserts().get(0).getId()); - default: - throw new MongoInternalException("Unhandled write request type: " + type); + throw translateSingleOperationBulkWriteResultException(type, e); } }