]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
Don't clobber the exception on rollback error in connection exit
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Fri, 15 Jan 2021 22:23:35 +0000 (23:23 +0100)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Sat, 16 Jan 2021 01:37:13 +0000 (02:37 +0100)
psycopg3/psycopg3/connection.py
tests/test_connection.py
tests/test_connection_async.py

index df221f59c877967e2746d24751ca6426adb4c5ab..1916f2ac57a23c9bcee4a85f58d3e0858928fe19 100644 (file)
@@ -430,7 +430,15 @@ class Connection(BaseConnection):
         exc_tb: Optional[TracebackType],
     ) -> None:
         if exc_type:
-            self.rollback()
+            # try to rollback, but if there are problems (connection in a bad
+            # state) just warn without clobbering the exception bubbling up.
+            try:
+                self.rollback()
+            except Exception as exc2:
+                warnings.warn(
+                    f"error rolling back the transaction on {self}: {exc2}",
+                    RuntimeWarning,
+                )
         else:
             self.commit()
 
@@ -558,7 +566,15 @@ class AsyncConnection(BaseConnection):
         exc_tb: Optional[TracebackType],
     ) -> None:
         if exc_type:
-            await self.rollback()
+            # try to rollback, but if there are problems (connection in a bad
+            # state) just warn without clobbering the exception bubbling up.
+            try:
+                await self.rollback()
+            except Exception as exc2:
+                warnings.warn(
+                    f"error rolling back the transaction on {self}: {exc2}",
+                    RuntimeWarning,
+                )
         else:
             await self.commit()
 
index 79c725db1f0e8ff33858039a6c7e1b0f45e6e59d..398900793bdbf1ae9dd69005e5bc566d4639c478 100644 (file)
@@ -134,6 +134,19 @@ def test_context_rollback(conn, dsn):
                 cur.execute("select * from textctx")
 
 
+def test_context_rollback_no_clobber(conn, dsn, recwarn):
+    with pytest.raises(ZeroDivisionError):
+        with psycopg3.connect(dsn) as conn2:
+            conn2.execute("select 1")
+            conn.execute(
+                "select pg_terminate_backend(%s::int)",
+                [conn2.pgconn.backend_pid],
+            )
+            1 / 0
+
+    assert "rolling back" in str(recwarn.pop(RuntimeWarning).message)
+
+
 def test_weakref(dsn):
     conn = psycopg3.connect(dsn)
     w = weakref.ref(conn)
index f24a56907836064ab5717f6e157ed081992862c7..71bfb6a1d0bfa1c858a8707cd347f0d40cbd71f9 100644 (file)
@@ -139,6 +139,19 @@ async def test_context_rollback(aconn, dsn):
                 await cur.execute("select * from textctx")
 
 
+async def test_context_rollback_no_clobber(conn, dsn, recwarn):
+    with pytest.raises(ZeroDivisionError):
+        async with await psycopg3.AsyncConnection.connect(dsn) as conn2:
+            await conn2.execute("select 1")
+            conn.execute(
+                "select pg_terminate_backend(%s::int)",
+                [conn2.pgconn.backend_pid],
+            )
+            1 / 0
+
+    assert "rolling back" in str(recwarn.pop(RuntimeWarning).message)
+
+
 async def test_weakref(dsn):
     conn = await psycopg3.AsyncConnection.connect(dsn)
     w = weakref.ref(conn)