Skip to content

Commit 7938d14

Browse files
committed
Improve MongoExceptionTranslator to accept MongoSocketException children.
Closes spring-projects#3568
1 parent 2ef9844 commit 7938d14

File tree

2 files changed

+48
-12
lines changed

2 files changed

+48
-12
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoExceptionTranslator.java

+23-9
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
*/
1616
package org.springframework.data.mongodb.core;
1717

18+
import static java.lang.String.format;
19+
import static java.util.Arrays.asList;
20+
1821
import java.util.Arrays;
1922
import java.util.Collections;
2023
import java.util.HashSet;
@@ -49,21 +52,28 @@
4952
* @author Oliver Gierke
5053
* @author Michal Vich
5154
* @author Christoph Strobl
55+
* @author Brice Vandeputte
5256
*/
5357
public class MongoExceptionTranslator implements PersistenceExceptionTranslator {
58+
/**
59+
* translation matrix definitions:
60+
* - adding {@code ClassShortName} will associate a given exception class to a translated group
61+
* - adding {@code ClassShortName$children} will associate a given exception direct children to a translated group
62+
*/
5463

5564
private static final Set<String> DUPLICATE_KEY_EXCEPTIONS = new HashSet<>(
56-
Arrays.asList("MongoException.DuplicateKey", "DuplicateKeyException"));
65+
asList("MongoException.DuplicateKey", "DuplicateKeyException"));
5766

5867
private static final Set<String> RESOURCE_FAILURE_EXCEPTIONS = new HashSet<>(
59-
Arrays.asList("MongoException.Network", "MongoSocketException", "MongoException.CursorNotFound",
60-
"MongoCursorNotFoundException", "MongoServerSelectionException", "MongoTimeoutException"));
68+
asList("MongoException.Network", "MongoSocketException", "MongoSocketException$children",
69+
"MongoException.CursorNotFound", "MongoCursorNotFoundException", "MongoServerSelectionException",
70+
"MongoTimeoutException"));
6171

6272
private static final Set<String> RESOURCE_USAGE_EXCEPTIONS = new HashSet<>(
6373
Collections.singletonList("MongoInternalException"));
6474

6575
private static final Set<String> DATA_INTEGRITY_EXCEPTIONS = new HashSet<>(
66-
Arrays.asList("WriteConcernException", "MongoWriteException", "MongoBulkWriteException"));
76+
asList("WriteConcernException", "MongoWriteException", "MongoBulkWriteException"));
6777

6878
/*
6979
* (non-Javadoc)
@@ -78,21 +88,25 @@ public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
7888
throw new InvalidDataAccessApiUsageException(ex.getMessage(), ex);
7989
}
8090

81-
String exception = ClassUtils.getShortName(ClassUtils.getUserClass(ex.getClass()));
91+
Class<? extends RuntimeException> exceptionClass = ex.getClass();
92+
String exception = ClassUtils.getShortName(ClassUtils.getUserClass(exceptionClass));
93+
String exceptionParentMatcher = format("%s$children",
94+
ClassUtils.getShortName(ClassUtils.getUserClass(exceptionClass.getSuperclass()))
95+
);
8296

83-
if (DUPLICATE_KEY_EXCEPTIONS.contains(exception)) {
97+
if (!Collections.disjoint(DUPLICATE_KEY_EXCEPTIONS, asList(exception, exceptionParentMatcher))) {
8498
return new DuplicateKeyException(ex.getMessage(), ex);
8599
}
86100

87-
if (RESOURCE_FAILURE_EXCEPTIONS.contains(exception)) {
101+
if (!Collections.disjoint(RESOURCE_FAILURE_EXCEPTIONS, asList(exception, exceptionParentMatcher))) {
88102
return new DataAccessResourceFailureException(ex.getMessage(), ex);
89103
}
90104

91-
if (RESOURCE_USAGE_EXCEPTIONS.contains(exception)) {
105+
if (!Collections.disjoint(RESOURCE_USAGE_EXCEPTIONS, asList(exception, exceptionParentMatcher))) {
92106
return new InvalidDataAccessResourceUsageException(ex.getMessage(), ex);
93107
}
94108

95-
if (DATA_INTEGRITY_EXCEPTIONS.contains(exception)) {
109+
if (!Collections.disjoint(DATA_INTEGRITY_EXCEPTIONS, asList(exception, exceptionParentMatcher))) {
96110

97111
if (ex instanceof MongoServerException) {
98112
if (((MongoServerException) ex).getCode() == 11000) {

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoExceptionTranslatorUnitTests.java

+25-3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717

1818
import static org.assertj.core.api.Assertions.*;
1919

20+
import com.mongodb.MongoSocketReadTimeoutException;
21+
import com.mongodb.MongoSocketWriteException;
22+
import java.io.IOException;
2023
import java.net.UnknownHostException;
2124

2225
import org.bson.BsonDocument;
@@ -45,9 +48,11 @@
4548
* @author Michal Vich
4649
* @author Oliver Gierke
4750
* @author Christoph Strobl
51+
* @author Brice Vandeputte
4852
*/
4953
public class MongoExceptionTranslatorUnitTests {
5054

55+
public static final String EXCEPTION_MESSAGE = "IOException";
5156
MongoExceptionTranslator translator;
5257

5358
@BeforeEach
@@ -68,13 +73,30 @@ public void translateDuplicateKey() {
6873
public void translateSocketException() {
6974

7075
expectExceptionWithCauseMessage(
71-
translator.translateExceptionIfPossible(new MongoSocketException("IOException", new ServerAddress())),
72-
DataAccessResourceFailureException.class, "IOException");
76+
translator.translateExceptionIfPossible(new MongoSocketException(EXCEPTION_MESSAGE, new ServerAddress())),
77+
DataAccessResourceFailureException.class, EXCEPTION_MESSAGE);
78+
79+
}
80+
81+
@Test // GH-3568
82+
public void translateSocketChildrenExceptions() {
83+
84+
expectExceptionWithCauseMessage(
85+
translator.translateExceptionIfPossible(
86+
new MongoSocketWriteException("intermediate message", new ServerAddress(), new Exception(EXCEPTION_MESSAGE))
87+
),
88+
DataAccessResourceFailureException.class, EXCEPTION_MESSAGE);
89+
90+
expectExceptionWithCauseMessage(
91+
translator.translateExceptionIfPossible(
92+
new MongoSocketReadTimeoutException("intermediate message", new ServerAddress(), new Exception(EXCEPTION_MESSAGE))
93+
),
94+
DataAccessResourceFailureException.class, EXCEPTION_MESSAGE);
7395

7496
}
7597

7698
@Test
77-
public void translateCursorNotFound() throws UnknownHostException {
99+
public void translateCursorNotFound() {
78100

79101
expectExceptionWithCauseMessage(
80102
translator.translateExceptionIfPossible(new MongoCursorNotFoundException(1L, new ServerAddress())),

0 commit comments

Comments
 (0)