DATAMONGO-81 - Added more unit tests for MongoExceptionTranslator.
This commit is contained in:
committed by
Oliver Gierke
parent
c28e51cf86
commit
782cf6e10d
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2011 the original author or authors.
|
* Copyright 2010-2013 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -15,12 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.core;
|
package org.springframework.data.mongodb.core;
|
||||||
|
|
||||||
import com.mongodb.MongoException;
|
|
||||||
import com.mongodb.MongoException.CursorNotFound;
|
|
||||||
import com.mongodb.MongoException.DuplicateKey;
|
|
||||||
import com.mongodb.MongoException.Network;
|
|
||||||
import com.mongodb.MongoInternalException;
|
|
||||||
|
|
||||||
import org.springframework.dao.DataAccessException;
|
import org.springframework.dao.DataAccessException;
|
||||||
import org.springframework.dao.DataAccessResourceFailureException;
|
import org.springframework.dao.DataAccessResourceFailureException;
|
||||||
import org.springframework.dao.DuplicateKeyException;
|
import org.springframework.dao.DuplicateKeyException;
|
||||||
@@ -29,21 +23,26 @@ import org.springframework.dao.InvalidDataAccessResourceUsageException;
|
|||||||
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||||
import org.springframework.data.mongodb.UncategorizedMongoDbException;
|
import org.springframework.data.mongodb.UncategorizedMongoDbException;
|
||||||
|
|
||||||
|
import com.mongodb.MongoException;
|
||||||
|
import com.mongodb.MongoException.CursorNotFound;
|
||||||
|
import com.mongodb.MongoException.DuplicateKey;
|
||||||
|
import com.mongodb.MongoException.Network;
|
||||||
|
import com.mongodb.MongoInternalException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple {@link PersistenceExceptionTranslator} for Mongo. Convert the given runtime exception to an appropriate
|
* Simple {@link PersistenceExceptionTranslator} for Mongo. Convert the given runtime exception to an appropriate
|
||||||
* exception from the {@code org.springframework.dao} hierarchy. Return {@literal null} if no translation is
|
* exception from the {@code org.springframework.dao} hierarchy. Return {@literal null} if no translation is
|
||||||
* appropriate: any other exception may have resulted from user code, and should not be translated.
|
* appropriate: any other exception may have resulted from user code, and should not be translated.
|
||||||
*
|
*
|
||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
|
* @author Michal Vich
|
||||||
*/
|
*/
|
||||||
public class MongoExceptionTranslator implements PersistenceExceptionTranslator {
|
public class MongoExceptionTranslator implements PersistenceExceptionTranslator {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
* @see org.springframework.dao.support.PersistenceExceptionTranslator#translateExceptionIfPossible(java.lang.RuntimeException)
|
||||||
* @see org.springframework.dao.support.PersistenceExceptionTranslator#
|
*/
|
||||||
* translateExceptionIfPossible(java.lang.RuntimeException)
|
|
||||||
*/
|
|
||||||
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
|
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
|
||||||
|
|
||||||
// Check for well-known MongoException subclasses.
|
// Check for well-known MongoException subclasses.
|
||||||
@@ -52,14 +51,23 @@ public class MongoExceptionTranslator implements PersistenceExceptionTranslator
|
|||||||
if (ex instanceof DuplicateKey) {
|
if (ex instanceof DuplicateKey) {
|
||||||
return new DuplicateKeyException(ex.getMessage(), ex);
|
return new DuplicateKeyException(ex.getMessage(), ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ex instanceof Network) {
|
if (ex instanceof Network) {
|
||||||
return new DataAccessResourceFailureException(ex.getMessage(), ex);
|
return new DataAccessResourceFailureException(ex.getMessage(), ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ex instanceof CursorNotFound) {
|
if (ex instanceof CursorNotFound) {
|
||||||
return new DataAccessResourceFailureException(ex.getMessage(), ex);
|
return new DataAccessResourceFailureException(ex.getMessage(), ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ex instanceof MongoInternalException) {
|
||||||
|
return new InvalidDataAccessResourceUsageException(ex.getMessage(), ex);
|
||||||
|
}
|
||||||
|
|
||||||
if (ex instanceof MongoException) {
|
if (ex instanceof MongoException) {
|
||||||
|
|
||||||
int code = ((MongoException) ex).getCode();
|
int code = ((MongoException) ex).getCode();
|
||||||
|
|
||||||
if (code == 11000 || code == 11001) {
|
if (code == 11000 || code == 11001) {
|
||||||
throw new DuplicateKeyException(ex.getMessage(), ex);
|
throw new DuplicateKeyException(ex.getMessage(), ex);
|
||||||
} else if (code == 12000 || code == 13440) {
|
} else if (code == 12000 || code == 13440) {
|
||||||
@@ -69,9 +77,6 @@ public class MongoExceptionTranslator implements PersistenceExceptionTranslator
|
|||||||
}
|
}
|
||||||
return new UncategorizedMongoDbException(ex.getMessage(), ex);
|
return new UncategorizedMongoDbException(ex.getMessage(), ex);
|
||||||
}
|
}
|
||||||
if (ex instanceof MongoInternalException) {
|
|
||||||
return new InvalidDataAccessResourceUsageException(ex.getMessage(), ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we get here, we have an exception that resulted from user code,
|
// If we get here, we have an exception that resulted from user code,
|
||||||
// rather than the persistence provider, so we return null to indicate
|
// rather than the persistence provider, so we return null to indicate
|
||||||
|
|||||||
@@ -0,0 +1,159 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 the original author or authors.
|
||||||
|
*
|
||||||
|
* 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 org.springframework.data.mongodb.core;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.core.NestedRuntimeException;
|
||||||
|
import org.springframework.dao.DataAccessException;
|
||||||
|
import org.springframework.dao.DataAccessResourceFailureException;
|
||||||
|
import org.springframework.dao.DuplicateKeyException;
|
||||||
|
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||||
|
import org.springframework.dao.InvalidDataAccessResourceUsageException;
|
||||||
|
import org.springframework.data.mongodb.UncategorizedMongoDbException;
|
||||||
|
|
||||||
|
import com.mongodb.MongoException;
|
||||||
|
import com.mongodb.MongoException.DuplicateKey;
|
||||||
|
import com.mongodb.MongoException.Network;
|
||||||
|
import com.mongodb.MongoInternalException;
|
||||||
|
import com.mongodb.ServerAddress;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for {@link MongoExceptionTranslator}.
|
||||||
|
*
|
||||||
|
* @author Michal Vich
|
||||||
|
* @author Oliver Gierke
|
||||||
|
*/
|
||||||
|
public class MongoExceptionTranslatorUnitTests {
|
||||||
|
|
||||||
|
MongoExceptionTranslator translator;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
translator = new MongoExceptionTranslator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void translateDuplicateKey() {
|
||||||
|
|
||||||
|
DuplicateKey exception = new DuplicateKey(1, "Duplicated key");
|
||||||
|
DataAccessException translatedException = translator.translateExceptionIfPossible(exception);
|
||||||
|
|
||||||
|
expectExceptionWithCauseMessage(translatedException, DuplicateKeyException.class, "Duplicated key");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void translateNetwork() {
|
||||||
|
|
||||||
|
Network exception = new Network("IOException", new IOException("IOException"));
|
||||||
|
DataAccessException translatedException = translator.translateExceptionIfPossible(exception);
|
||||||
|
|
||||||
|
expectExceptionWithCauseMessage(translatedException, DataAccessResourceFailureException.class, "IOException");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void translateCursorNotFound() throws UnknownHostException {
|
||||||
|
|
||||||
|
MongoException.CursorNotFound exception = new MongoException.CursorNotFound(1, new ServerAddress());
|
||||||
|
DataAccessException translatedException = translator.translateExceptionIfPossible(exception);
|
||||||
|
|
||||||
|
expectExceptionWithCauseMessage(translatedException, DataAccessResourceFailureException.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void translateToDuplicateKeyException() {
|
||||||
|
|
||||||
|
checkTranslatedMongoException(DuplicateKeyException.class, 11000);
|
||||||
|
checkTranslatedMongoException(DuplicateKeyException.class, 11001);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void translateToDataAccessResourceFailureException() {
|
||||||
|
|
||||||
|
checkTranslatedMongoException(DataAccessResourceFailureException.class, 12000);
|
||||||
|
checkTranslatedMongoException(DataAccessResourceFailureException.class, 13440);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void translateToInvalidDataAccessApiUsageException() {
|
||||||
|
|
||||||
|
checkTranslatedMongoException(InvalidDataAccessApiUsageException.class, 10003);
|
||||||
|
checkTranslatedMongoException(InvalidDataAccessApiUsageException.class, 12001);
|
||||||
|
checkTranslatedMongoException(InvalidDataAccessApiUsageException.class, 12010);
|
||||||
|
checkTranslatedMongoException(InvalidDataAccessApiUsageException.class, 12011);
|
||||||
|
checkTranslatedMongoException(InvalidDataAccessApiUsageException.class, 12012);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void translateToUncategorizedMongoDbException() {
|
||||||
|
|
||||||
|
MongoException exception = new MongoException(0, "");
|
||||||
|
DataAccessException translatedException = translator.translateExceptionIfPossible(exception);
|
||||||
|
|
||||||
|
expectExceptionWithCauseMessage(translatedException, UncategorizedMongoDbException.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void translateMongoInternalException() {
|
||||||
|
|
||||||
|
MongoInternalException exception = new MongoInternalException("Internal exception");
|
||||||
|
DataAccessException translatedException = translator.translateExceptionIfPossible(exception);
|
||||||
|
|
||||||
|
expectExceptionWithCauseMessage(translatedException, InvalidDataAccessResourceUsageException.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void translateUnsupportedException() {
|
||||||
|
|
||||||
|
RuntimeException exception = new RuntimeException();
|
||||||
|
assertThat(translator.translateExceptionIfPossible(exception), is(nullValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkTranslatedMongoException(Class<? extends Exception> clazz, int code) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
translator.translateExceptionIfPossible(new MongoException(code, ""));
|
||||||
|
fail("Expected exception of type " + clazz.getName() + "!");
|
||||||
|
} catch (NestedRuntimeException e) {
|
||||||
|
Throwable cause = e.getRootCause();
|
||||||
|
assertThat(cause, is(instanceOf(MongoException.class)));
|
||||||
|
assertThat(((MongoException) cause).getCode(), is(code));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void expectExceptionWithCauseMessage(NestedRuntimeException e,
|
||||||
|
Class<? extends NestedRuntimeException> type) {
|
||||||
|
expectExceptionWithCauseMessage(e, type, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void expectExceptionWithCauseMessage(NestedRuntimeException e,
|
||||||
|
Class<? extends NestedRuntimeException> type, String message) {
|
||||||
|
|
||||||
|
assertThat(e, is(instanceOf(type)));
|
||||||
|
|
||||||
|
if (message != null) {
|
||||||
|
assertThat(e.getRootCause(), is(notNullValue()));
|
||||||
|
assertThat(e.getRootCause().getMessage(), containsString(message));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user