]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- move inner calls to _revalidate_connection() outside of existing
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 5 Dec 2014 21:34:43 +0000 (16:34 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 5 Dec 2014 21:34:43 +0000 (16:34 -0500)
_handle_dbapi_error(); these are now handled already and the reentrant
call is not needed / breaks things.  Adjustment to 41e7253dee168b8c26c49 /

lib/sqlalchemy/engine/base.py
test/engine/test_parseconnect.py

index 901ab07eb34cec3196459fecb8c2ec92589fc715..235e1bf438dc9777e85e700ed318763317720142 100644 (file)
@@ -814,11 +814,11 @@ class Connection(Connectable):
                     fn(self, default, multiparams, params)
 
         try:
-            try:
-                conn = self.__connection
-            except AttributeError:
-                conn = self._revalidate_connection()
+            conn = self.__connection
+        except AttributeError:
+            conn = self._revalidate_connection()
 
+        try:
             dialect = self.dialect
             ctx = dialect.execution_ctx_cls._init_default(
                 dialect, self, conn)
@@ -952,11 +952,11 @@ class Connection(Connectable):
         a :class:`.ResultProxy`."""
 
         try:
-            try:
-                conn = self.__connection
-            except AttributeError:
-                conn = self._revalidate_connection()
+            conn = self.__connection
+        except AttributeError:
+            conn = self._revalidate_connection()
 
+        try:
             context = constructor(dialect, self, conn, *args)
         except Exception as e:
             self._handle_dbapi_exception(e,
@@ -1246,6 +1246,7 @@ class Connection(Connectable):
     @classmethod
     def _handle_dbapi_exception_noconnection(
             cls, e, dialect, engine, connection):
+
         exc_info = sys.exc_info()
 
         is_disconnect = dialect.is_disconnect(e, None, None)
index 72a089acaa934a598216e69a4136a2bbd0d51e7d..b6d08cebaaf292a40598fde1a1f570c1b406e5c3 100644 (file)
@@ -7,6 +7,7 @@ from sqlalchemy.testing import fixtures
 from sqlalchemy import testing
 from sqlalchemy.testing.mock import Mock, MagicMock
 from sqlalchemy import event
+from sqlalchemy import select
 
 dialect = None
 
@@ -279,7 +280,7 @@ class CreateEngineTest(fixtures.TestBase):
         )
 
     @testing.requires.sqlite
-    def test_handle_error_event_reconnect(self):
+    def test_handle_error_event_revalidate(self):
         e = create_engine('sqlite://')
         dbapi = MockDBAPI()
         sqlite3 = e.dialect.dbapi
@@ -295,6 +296,7 @@ class CreateEngineTest(fixtures.TestBase):
         def handle_error(ctx):
             assert ctx.engine is eng
             assert ctx.connection is conn
+            assert isinstance(ctx.sqlalchemy_exception, exc.ProgrammingError)
             raise MySpecialException("failed operation")
 
         conn = eng.connect()
@@ -308,6 +310,37 @@ class CreateEngineTest(fixtures.TestBase):
             conn._revalidate_connection
         )
 
+    @testing.requires.sqlite
+    def test_handle_error_event_implicit_revalidate(self):
+        e = create_engine('sqlite://')
+        dbapi = MockDBAPI()
+        sqlite3 = e.dialect.dbapi
+        dbapi.Error = sqlite3.Error,
+        dbapi.ProgrammingError = sqlite3.ProgrammingError
+
+        class MySpecialException(Exception):
+            pass
+
+        eng = create_engine('sqlite://', module=dbapi, _initialize=False)
+
+        @event.listens_for(eng, "handle_error")
+        def handle_error(ctx):
+            assert ctx.engine is eng
+            assert ctx.connection is conn
+            assert isinstance(ctx.sqlalchemy_exception, exc.ProgrammingError)
+            raise MySpecialException("failed operation")
+
+        conn = eng.connect()
+        conn.invalidate()
+
+        dbapi.connect = Mock(
+            side_effect=sqlite3.ProgrammingError("random error"))
+
+        assert_raises(
+            MySpecialException,
+            conn.execute, select([1])
+        )
+
     @testing.requires.sqlite
     def test_handle_error_custom_connect(self):
         e = create_engine('sqlite://')