]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
fix: improve error message trying to fetch from a no recordset result
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Fri, 2 May 2025 22:18:10 +0000 (00:18 +0200)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Thu, 8 May 2025 21:18:29 +0000 (23:18 +0200)
Print the last command status with the error. For example:

    the last operation didn't produce records (command status: NOTIFY)

or, if the result doesn't even have a command status:

    the last operation didn't produce records (result status: EMPTY_QUERY)

psycopg/psycopg/_cursor_base.py
tests/test_cursor_common.py
tests/test_cursor_common_async.py

index 3a1d6d45b361dc20c27facd47d138b3ee816ab9c..f6e85f19057e4be64af5d5388a0d70459b0adb51 100644 (file)
@@ -579,7 +579,17 @@ class BaseCursor(Generic[ConnectionType, Row]):
         elif status == PIPELINE_ABORTED:
             raise e.PipelineAborted("pipeline aborted")
         else:
-            raise e.ProgrammingError("the last operation didn't produce a result")
+            if res.command_status:
+                detail = f" (command status: {res.command_status.decode()})"
+            else:
+                try:
+                    status_name = pq.ExecStatus(status).name
+                except ValueError:
+                    status_name = f"{status} - unknown"
+                detail = f" (result status: {status_name})"
+            raise e.ProgrammingError(
+                f"the last operation didn't produce records{detail}"
+            )
 
     def _check_copy_result(self, result: PGresult) -> None:
         """
index f1fcf665d8993f7c3205c5591ff4f761be198e58..d99f734e033558bd37a51a19550680b2bce5dfbd 100644 (file)
@@ -865,3 +865,21 @@ def test_message_0x33(conn):
 def test_typeinfo(conn):
     info = TypeInfo.fetch(conn, "jsonb")
     assert info is not None
+
+
+def test_error_no_result(conn):
+    cur = conn.cursor()
+    with pytest.raises(psycopg.ProgrammingError, match="no result available"):
+        cur.fetchone()
+
+    cur.execute("set timezone to utc")
+    with pytest.raises(
+        psycopg.ProgrammingError, match="last operation.*command status: SET"
+    ):
+        cur.fetchone()
+
+    cur.execute("")
+    with pytest.raises(
+        psycopg.ProgrammingError, match="last operation.*result status: EMPTY_QUERY"
+    ):
+        cur.fetchone()
index 9a96785c8b7550dd807ec8376d07fe5c7a940533..03e5ef6b0fe5795e5e841cf77e00a0acfdc7dc9f 100644 (file)
@@ -872,3 +872,21 @@ async def test_message_0x33(aconn):
 async def test_typeinfo(aconn):
     info = await TypeInfo.fetch(aconn, "jsonb")
     assert info is not None
+
+
+async def test_error_no_result(aconn):
+    cur = aconn.cursor()
+    with pytest.raises(psycopg.ProgrammingError, match="no result available"):
+        await cur.fetchone()
+
+    await cur.execute("set timezone to utc")
+    with pytest.raises(
+        psycopg.ProgrammingError, match="last operation.*command status: SET"
+    ):
+        await cur.fetchone()
+
+    await cur.execute("")
+    with pytest.raises(
+        psycopg.ProgrammingError, match="last operation.*result status: EMPTY_QUERY"
+    ):
+        await cur.fetchone()