Implement further exception handling improvements.

master
baztian 2015-04-10 08:22:03 +02:00
parent a2ba0fb2b1
commit 4ededf479d
4 changed files with 90 additions and 29 deletions

View File

@ -173,6 +173,9 @@ Changelog
- Enrich exceptions with message from java SQLExceptions
- Be more specific about DB API exceptions: Distinguish DatabaseError and
InterfaceError.
- Fix typo LONGNARCHAR vs LONGVARCHAR (thanks @datdo for reporting #4)
- 0.1.5 - 2015-03-02

View File

@ -13,9 +13,20 @@ public abstract class MockConnection implements Connection {
ResultSet mockResultSet;
public final void mockExceptionOnExecute(String exceptionMessage) throws SQLException {
public final void mockExceptionOnCommit(String className, String exceptionMessage) throws SQLException {
Throwable exception = createException(className, exceptionMessage);
Mockito.doThrow(exception).when(this).commit();
}
public final void mockExceptionOnRollback(String className, String exceptionMessage) throws SQLException {
Throwable exception = createException(className, exceptionMessage);
Mockito.doThrow(exception).when(this).rollback();
}
public final void mockExceptionOnExecute(String className, String exceptionMessage) throws SQLException {
PreparedStatement mockPreparedStatement = Mockito.mock(PreparedStatement.class);
Mockito.when(mockPreparedStatement.execute()).thenThrow(new SQLException(exceptionMessage));
Throwable exception = createException(className, exceptionMessage);
Mockito.when(mockPreparedStatement.execute()).thenThrow(exception);
Mockito.when(this.prepareStatement(Mockito.anyString())).thenReturn(mockPreparedStatement);
}
@ -33,7 +44,19 @@ public abstract class MockConnection implements Connection {
Mockito.when(this.prepareStatement(Mockito.anyString())).thenReturn(mockPreparedStatement);
}
private int extractTypeCodeForName(String sqlTypesName) {
public final ResultSet verifyResultSet() {
return Mockito.verify(mockResultSet);
}
private static Throwable createException(String className, String exceptionMessage) {
try {
return (Throwable) Class.forName(className).getConstructor(String.class).newInstance(exceptionMessage);
} catch (Exception e) {
throw new RuntimeException("Couldn't initialize class " + className + ".", e);
}
}
private static int extractTypeCodeForName(String sqlTypesName) {
try {
Field field = Types.class.getField(sqlTypesName);
return field.getInt(null);
@ -48,8 +71,4 @@ public abstract class MockConnection implements Connection {
}
}
public final ResultSet verifyResultSet() {
return Mockito.verify(mockResultSet);
}
}

View File

@ -41,13 +41,14 @@ _java_array_byte = None
_handle_sql_exception = None
def _handle_sql_exception_jython(ex):
def _handle_sql_exception_jython():
from java.sql import SQLException
if isinstance(ex, SQLException):
# TODO get stacktrace
raise Error, ex.getMessage()
exc_info = sys.exc_info()
if isinstance(exc_info[1], SQLException):
exc_type = DatabaseError
else:
raise ex
exc_type = InterfaceError
raise exc_type, exc_info[1], exc_info[2]
def _jdbc_connect_jython(jclassname, jars, libs, *args):
if _jdbc_name_to_const is None:
@ -103,14 +104,15 @@ def _prepare_jython():
global _handle_sql_exception
_handle_sql_exception = _handle_sql_exception_jython
def _handle_sql_exception_jpype(ex):
def _handle_sql_exception_jpype():
import jpype
SQLException = jpype.java.sql.SQLException
if issubclass(ex.__javaclass__, SQLException):
# TODO get stacktrace
raise Error, ex.message()
exc_info = sys.exc_info()
if issubclass(exc_info[1].__javaclass__, SQLException):
exc_type = DatabaseError
else:
raise ex
exc_type = InterfaceError
raise exc_type, exc_info[1], exc_info[2]
def _jdbc_connect_jpype(jclassname, jars, libs, *driver_args):
import jpype
@ -353,15 +355,13 @@ class Connection(object):
try:
self.jconn.commit()
except:
ex = sys.exc_info()[1]
_handle_sql_exception(ex)
_handle_sql_exception()
def rollback(self):
try:
self.jconn.rollback()
except:
ex = sys.exc_info()[1]
_handle_sql_exception(ex)
_handle_sql_exception()
def cursor(self):
return Cursor(self, self._converters)
@ -445,8 +445,7 @@ class Cursor(object):
try:
is_rs = self._prep.execute()
except:
ex = sys.exc_info()[1]
_handle_sql_exception(ex)
_handle_sql_exception()
if is_rs:
self._rs = self._prep.getResultSet()
self._meta = self._rs.getMetaData()
@ -454,7 +453,7 @@ class Cursor(object):
else:
self.rowcount = self._prep.getUpdateCount()
# self._prep.getWarnings() ???
def executemany(self, operation, seq_of_parameters):
self._close_last()
self._prep = self._connection.jconn.prepareStatement(operation)

View File

@ -47,12 +47,52 @@ class MockTest(unittest.TestCase):
'getObject'))
verify_get(1)
def test_exception_on_execute(self):
dummy_msg = "expected"
self.conn.jconn.mockExceptionOnExecute(dummy_msg)
def test_sql_exception_on_execute(self):
self.conn.jconn.mockExceptionOnExecute("java.sql.SQLException", "expected")
cursor = self.conn.cursor()
try:
cursor.execute("dummy stmt")
fail("expected exception")
except jaydebeapi.Error, e:
self.assertEquals(str(e), 'expected')
except jaydebeapi.DatabaseError, e:
self.assertEquals(str(e), "java.sql.SQLException: expected")
def test_runtime_exception_on_execute(self):
self.conn.jconn.mockExceptionOnExecute("java.lang.RuntimeException", "expected")
cursor = self.conn.cursor()
try:
cursor.execute("dummy stmt")
fail("expected exception")
except jaydebeapi.InterfaceError, e:
self.assertEquals(str(e), "java.lang.RuntimeException: expected")
def test_sql_exception_on_commit(self):
self.conn.jconn.mockExceptionOnCommit("java.sql.SQLException", "expected")
try:
self.conn.commit()
fail("expected exception")
except jaydebeapi.DatabaseError, e:
self.assertEquals(str(e), "java.sql.SQLException: expected")
def test_runtime_exception_on_commit(self):
self.conn.jconn.mockExceptionOnCommit("java.lang.RuntimeException", "expected")
try:
self.conn.commit()
fail("expected exception")
except jaydebeapi.InterfaceError, e:
self.assertEquals(str(e), "java.lang.RuntimeException: expected")
def test_sql_exception_on_rollback(self):
self.conn.jconn.mockExceptionOnRollback("java.sql.SQLException", "expected")
try:
self.conn.rollback()
fail("expected exception")
except jaydebeapi.DatabaseError, e:
self.assertEquals(str(e), "java.sql.SQLException: expected")
def test_runtime_exception_on_rollback(self):
self.conn.jconn.mockExceptionOnRollback("java.lang.RuntimeException", "expected")
try:
self.conn.rollback()
fail("expected exception")
except jaydebeapi.InterfaceError, e:
self.assertEquals(str(e), "java.lang.RuntimeException: expected")