From: Daniele Varrazzo Date: Tue, 1 Jun 2021 23:03:44 +0000 (+0100) Subject: Raise multi-line error messages with context X-Git-Tag: 3.0.dev0~40 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=956238bef739675d46d6e65c953c1dcef10a165e;p=thirdparty%2Fpsycopg.git Raise multi-line error messages with context 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. --- diff --git a/psycopg3/psycopg3/pq/misc.py b/psycopg3/psycopg3/pq/misc.py index 7eb8d69be..f5957e7e3 100644 --- a/psycopg3/psycopg3/pq/misc.py +++ b/psycopg3/psycopg3/pq/misc.py @@ -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( diff --git a/tests/pq/test_misc.py b/tests/pq/test_misc.py index 7aa96d887..60355ea25 100644 --- a/tests/pq/test_misc.py +++ b/tests/pq/test_misc.py @@ -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) diff --git a/tests/test_errors.py b/tests/test_errors.py index 663d1132d..37b91178b 100644 --- a/tests/test_errors.py +++ b/tests/test_errors.py @@ -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")