Implement further exception handling improvements.
parent
a2ba0fb2b1
commit
4ededf479d
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
Loading…
Reference in New Issue