]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
Raise multi-line error messages with context
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Tue, 1 Jun 2021 23:03:44 +0000 (00:03 +0100)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Tue, 1 Jun 2021 23:11:20 +0000 (00:11 +0100)
The context is not available in the diag error. Debugging without it is
pretty hard.

Make sure the error doesn't end with a newline, which is a complaint of
psycopg2.

psycopg3/psycopg3/pq/misc.py
tests/pq/test_misc.py
tests/test_errors.py

index 7eb8d69be01eb3c642c37215fe02cf37eeb07858..f5957e7e37b2ac7d096b6a07de6c0a344f934dbc 100644 (file)
@@ -6,7 +6,7 @@ Various functionalities to make easier to work with the libpq.
 
 from typing import cast, NamedTuple, Optional, Union
 
-from ._enums import DiagnosticField, ConnStatus, TransactionStatus
+from ._enums import ConnStatus, TransactionStatus
 from .proto import PGconn, PGresult
 
 
@@ -51,14 +51,11 @@ def error_message(obj: Union[PGconn, PGresult], encoding: str = "utf8") -> str:
     if hasattr(obj, "error_field"):
         # obj is a PGresult
         obj = cast(PGresult, obj)
+        bmsg = obj.error_message
 
-        bmsg = obj.error_field(DiagnosticField.MESSAGE_PRIMARY) or b""
-        if not bmsg:
-            bmsg = obj.error_message
-
-            # strip severity and whitespaces
-            if bmsg:
-                bmsg = bmsg.splitlines()[0].split(b":", 1)[-1].strip()
+        # strip severity and whitespaces
+        if bmsg:
+            bmsg = bmsg.split(b":", 1)[-1].strip()
 
     elif hasattr(obj, "error_message"):
         from psycopg3.encodings import py_codecs
@@ -73,7 +70,7 @@ def error_message(obj: Union[PGconn, PGresult], encoding: str = "utf8") -> str:
 
         # strip severity and whitespaces
         if bmsg:
-            bmsg = bmsg.splitlines()[0].split(b":", 1)[-1].strip()
+            bmsg = bmsg.split(b":", 1)[-1].strip()
 
     else:
         raise TypeError(
index 7aa96d88768c8d6cc41aab7eb701ad86b0af4bb1..60355ea250aa53b6072daec8971ae4b048eb445e 100644 (file)
@@ -8,11 +8,10 @@ def test_error_message(pgconn):
     res = pgconn.exec_(b"wat")
     assert res.status == pq.ExecStatus.FATAL_ERROR
     msg = pq.error_message(pgconn)
-    assert msg == 'syntax error at or near "wat"'
+    assert msg == 'syntax error at or near "wat"\nLINE 1: wat\n        ^'
     assert msg == pq.error_message(res)
-    assert msg == res.error_field(pq.DiagnosticField.MESSAGE_PRIMARY).decode(
-        "ascii"
-    )
+    primary = res.error_field(pq.DiagnosticField.MESSAGE_PRIMARY)
+    assert primary.decode("ascii") in msg
 
     with pytest.raises(TypeError):
         pq.error_message(None)
index 663d1132de10d15d9e0032df2ec6fdee2bf8e1f2..37b91178b7a15ec5fc19c924cdf42b6c00c114d8 100644 (file)
@@ -215,3 +215,14 @@ async def test_diag_from_commit_async(aconn):
         await aconn.commit()
 
     assert exc.value.diag.sqlstate == "23503"
+
+
+def test_query_context(conn):
+    with pytest.raises(e.Error) as exc:
+        conn.execute("select * from wat")
+
+    s = str(exc.value)
+    assert "from wat" in s, s
+    assert exc.value.diag.message_primary in s
+    assert "ERROR" not in s
+    assert not s.endswith("\n")