Skip to content

Commit f77e7b5

Browse files
committed
JAVA-2815: Complete error label support
1 parent 2ddef35 commit f77e7b5

File tree

15 files changed

+1108
-35
lines changed

15 files changed

+1108
-35
lines changed

driver-async/src/main/com/mongodb/async/client/ClientSessionImpl.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
import com.mongodb.ClientSessionOptions;
2020
import com.mongodb.MongoClientException;
21-
import com.mongodb.MongoException;
2221
import com.mongodb.MongoInternalException;
2322
import com.mongodb.ReadConcern;
2423
import com.mongodb.TransactionOptions;
@@ -29,8 +28,6 @@
2928
import com.mongodb.operation.AbortTransactionOperation;
3029
import com.mongodb.operation.CommitTransactionOperation;
3130

32-
import static com.mongodb.MongoException.TRANSIENT_TRANSACTION_ERROR_LABEL;
33-
import static com.mongodb.MongoException.UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL;
3431
import static com.mongodb.assertions.Assertions.isTrue;
3532
import static com.mongodb.assertions.Assertions.notNull;
3633

@@ -129,13 +126,6 @@ public void commitTransaction(final SingleResultCallback<Void> callback) {
129126
public void onResult(final Void result, final Throwable t) {
130127
commitInProgress = false;
131128
transactionState = TransactionState.COMMITTED;
132-
if (t instanceof MongoException) {
133-
MongoException e = (MongoException) t;
134-
if (e.hasErrorLabel(TRANSIENT_TRANSACTION_ERROR_LABEL)) {
135-
e.removeLabel(TRANSIENT_TRANSACTION_ERROR_LABEL);
136-
e.addLabel(UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL);
137-
}
138-
}
139129
callback.onResult(result, t);
140130
}
141131
});

driver-async/src/main/com/mongodb/async/client/OperationExecutorImpl.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
import com.mongodb.operation.AsyncReadOperation;
3434
import com.mongodb.operation.AsyncWriteOperation;
3535

36+
import static com.mongodb.MongoException.TRANSIENT_TRANSACTION_ERROR_LABEL;
37+
import static com.mongodb.MongoException.UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL;
3638
import static com.mongodb.ReadPreference.primary;
3739
import static com.mongodb.assertions.Assertions.notNull;
3840
import static com.mongodb.internal.async.ErrorHandlingResultCallback.errorHandlingCallback;
@@ -109,8 +111,9 @@ public void onResult(final ClientSession clientSession, final Throwable t) {
109111
@Override
110112
public void onResult(final T result, final Throwable t) {
111113
try {
112-
if (t instanceof MongoSocketException && session != null && session.hasActiveTransaction()) {
113-
((MongoException) t).addLabel(MongoException.TRANSIENT_TRANSACTION_ERROR_LABEL);
114+
if (t instanceof MongoSocketException && session != null && session.hasActiveTransaction()
115+
&& !((MongoException) t).hasErrorLabel(UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL)) {
116+
((MongoException) t).addLabel(TRANSIENT_TRANSACTION_ERROR_LABEL);
114117
}
115118
errHandlingCallback.onResult(result, t);
116119
} finally {

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
1616

1717
package com.mongodb;
1818

19+
import org.bson.BsonArray;
1920
import org.bson.BsonDocument;
2021
import org.bson.BsonInt32;
2122
import org.bson.BsonString;
23+
import org.bson.BsonValue;
2224
import org.bson.codecs.BsonDocumentCodec;
2325
import org.bson.codecs.EncoderContext;
2426
import org.bson.json.JsonWriter;
@@ -48,6 +50,9 @@ public MongoCommandException(final BsonDocument response, final ServerAddress ad
4850
format("Command failed with error %s: '%s' on server %s. The full response is %s", extractErrorCodeAndName(response),
4951
extractErrorMessage(response), address, getResponseAsJson(response)), address);
5052
this.response = response;
53+
for (BsonValue curErrorLabel : response.getArray("errorLabels", new BsonArray())) {
54+
addLabel(curErrorLabel.asString().getValue());
55+
}
5156
}
5257

5358
/**

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

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,36 @@
1616

1717
package com.mongodb;
1818

19+
import org.bson.BsonDocument;
20+
1921
/**
2022
* An exception indicating that the server is a member of a replica set but is in recovery mode, and therefore refused to execute
2123
* the operation. This can happen when a server is starting up and trying to join the replica set.
2224
*
2325
* @since 3.0
2426
*/
25-
public class MongoNodeIsRecoveringException extends MongoServerException {
27+
public class MongoNodeIsRecoveringException extends MongoCommandException {
2628
private static final long serialVersionUID = 6062524147327071635L;
2729

30+
/**
31+
* Construct an instance.
32+
*
33+
* @param response the full response from the server
34+
* @param serverAddress the address of the server
35+
* @since 3.8
36+
*/
37+
public MongoNodeIsRecoveringException(final BsonDocument response, final ServerAddress serverAddress) {
38+
super(response, serverAddress);
39+
}
40+
2841
/**
2942
* Construct an instance.
3043
*
3144
* @param serverAddress the address of the server
45+
* @deprecated Prefer {@link #MongoNodeIsRecoveringException(BsonDocument, ServerAddress)}
3246
*/
47+
@Deprecated
3348
public MongoNodeIsRecoveringException(final ServerAddress serverAddress) {
34-
super("The server is in recovery mode and did not execute the operation", serverAddress);
49+
super(new BsonDocument(), serverAddress);
3550
}
3651
}

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

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,36 @@
1616

1717
package com.mongodb;
1818

19+
import org.bson.BsonDocument;
20+
1921
/**
2022
* An exception indicating that the server is a member of a replica set but is not the primary, and therefore refused to execute either a
2123
* write operation or a read operation that required a primary. This can happen during a replica set election.
2224
*
2325
* @since 3.0
2426
*/
25-
public class MongoNotPrimaryException extends MongoServerException {
27+
public class MongoNotPrimaryException extends MongoCommandException {
2628
private static final long serialVersionUID = 694876345217027108L;
2729

30+
/**
31+
* Construct an instance.
32+
*
33+
* @param response the full response from the server
34+
* @param serverAddress the address of the server
35+
* @since 3.8
36+
*/
37+
public MongoNotPrimaryException(final BsonDocument response, final ServerAddress serverAddress) {
38+
super(response, serverAddress);
39+
}
40+
2841
/**
2942
* Construct an instance.
3043
*
3144
* @param serverAddress the address of the server
45+
* @deprecated Prefer {@link #MongoNotPrimaryException(BsonDocument, ServerAddress)}
3246
*/
47+
@Deprecated
3348
public MongoNotPrimaryException(final ServerAddress serverAddress) {
34-
super("The server is not the primary and did not execute the operation", serverAddress);
49+
super(new BsonDocument(), serverAddress);
3550
}
3651
}

driver-core/src/main/com/mongodb/internal/connection/ProtocolHelper.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,9 +240,9 @@ public static MongoException createSpecialException(final BsonDocument response,
240240
return new MongoExecutionTimeoutException(errorCode, errorMessage);
241241
} else if (errorMessage.contains("not master or secondary") || errorMessage.contains("node is recovering")
242242
|| RECOVERING_CODES.contains(errorCode)) {
243-
return new MongoNodeIsRecoveringException(serverAddress);
243+
return new MongoNodeIsRecoveringException(response, serverAddress);
244244
} else if (errorMessage.contains("not master") || NOT_MASTER_CODES.contains(errorCode)) {
245-
return new MongoNotPrimaryException(serverAddress);
245+
return new MongoNotPrimaryException(response, serverAddress);
246246
} else if (response.containsKey("writeConcernError")) {
247247
return createSpecialException(response.getDocument("writeConcernError"), serverAddress, "errmsg");
248248
} else {

driver-core/src/main/com/mongodb/operation/CommandOperationHelper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@ public void onResult(final T result, final Throwable t) {
604604
}
605605

606606
private static final List<Integer> RETRYABLE_ERROR_CODES = asList(6, 7, 89, 91, 189, 9001, 13436, 13435, 11602, 11600, 10107);
607-
private static boolean isRetryableException(final Throwable t) {
607+
static boolean isRetryableException(final Throwable t) {
608608
if (!(t instanceof MongoException)) {
609609
return false;
610610
}

driver-core/src/main/com/mongodb/operation/CommitTransactionOperation.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,14 @@
1616

1717
package com.mongodb.operation;
1818

19+
import com.mongodb.MongoException;
1920
import com.mongodb.WriteConcern;
21+
import com.mongodb.async.SingleResultCallback;
22+
import com.mongodb.binding.AsyncWriteBinding;
23+
import com.mongodb.binding.WriteBinding;
24+
25+
import static com.mongodb.MongoException.UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL;
26+
import static com.mongodb.operation.CommandOperationHelper.isRetryableException;
2027

2128
/**
2229
* An operation that commits a transaction.
@@ -34,6 +41,35 @@ public CommitTransactionOperation(final WriteConcern writeConcern) {
3441
super(writeConcern);
3542
}
3643

44+
@Override
45+
public Void execute(final WriteBinding binding) {
46+
try {
47+
return super.execute(binding);
48+
} catch (MongoException e) {
49+
addErrorLabels(e);
50+
throw e;
51+
}
52+
}
53+
54+
@Override
55+
public void executeAsync(final AsyncWriteBinding binding, final SingleResultCallback<Void> callback) {
56+
super.executeAsync(binding, new SingleResultCallback<Void>() {
57+
@Override
58+
public void onResult(final Void result, final Throwable t) {
59+
if (t instanceof MongoException) {
60+
addErrorLabels((MongoException) t);
61+
}
62+
callback.onResult(result, t);
63+
}
64+
});
65+
}
66+
67+
private void addErrorLabels(final MongoException e) {
68+
if (isRetryableException(e)) {
69+
e.addLabel(UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL);
70+
}
71+
}
72+
3773
@Override
3874
protected String getCommandName() {
3975
return "commitTransaction";

driver-core/src/test/resources/transactions/abort.json

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,11 @@
441441
}
442442
},
443443
"result": {
444-
"errorCodeName": "DuplicateKey"
444+
"errorCodeName": "DuplicateKey",
445+
"errorLabelsOmit": [
446+
"TransientTransactionError",
447+
"UnknownTransactionCommitResult"
448+
]
445449
}
446450
},
447451
{
@@ -454,7 +458,13 @@
454458
}
455459
},
456460
"result": {
457-
"errorCodeName": "NoSuchTransaction"
461+
"errorCodeName": "NoSuchTransaction",
462+
"errorLabelsContain": [
463+
"TransientTransactionError"
464+
],
465+
"errorLabelsOmit": [
466+
"UnknownTransactionCommitResult"
467+
]
458468
}
459469
},
460470
{

driver-core/src/test/resources/transactions/commit.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,10 @@
379379
"name": "commitTransaction",
380380
"object": "session0",
381381
"result": {
382-
"errorCodeName": "CannotSatisfyWriteConcern"
382+
"errorLabelsOmit": [
383+
"TransientTransactionError",
384+
"UnknownTransactionCommitResult"
385+
]
383386
}
384387
}
385388
],

0 commit comments

Comments
 (0)