]> 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>
Sun, 4 May 2025 15:57:12 +0000 (16:57 +0100)
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 7fa31125cb6adb48b0c73e13bbadd5284dc2e84c..ee7c6462bb6b414f0998eae64b56c1558fa9b990 100644 (file)
@@ -583,7 +583,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 a2ca4af2af04d8156abe2ea17fec6680be051a5c..e6237148b4e75a146db89a57911747de20a25c61 100644 (file)
@@ -867,3 +867,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 252cd928c5d4af0150ddfcf70339305ec93ac9f5..ae07fb67adf42b5e7d7e42813060670511e21228 100644 (file)
@@ -874,3 +874,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()