From fb5e14c701215b2eb54e13007feae915738af32c Mon Sep 17 00:00:00 2001 From: Daniele Varrazzo Date: Wed, 16 Oct 2013 15:28:16 +0100 Subject: [PATCH] Meaningful connection errors report a meaningful message Fixes issue #173. Conflicts: NEWS --- NEWS | 2 ++ psycopg/connection_int.c | 7 ++++++- tests/test_async.py | 10 ++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 46121cd7..ec6d94e4 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,8 @@ What's new in psycopg 2.4.7 declared (:ticket:`#146`). - Fixed bad interaction of setup.py with other dependencies in Distribute project on Python 3 (ticket #153). + - Meaningful connection errors report a meaningful message, thanks to + Alexey Borzenkov (:ticket:`#173`). What's new in psycopg 2.4.6 diff --git a/psycopg/connection_int.c b/psycopg/connection_int.c index 59a14209..dcfeb0bc 100644 --- a/psycopg/connection_int.c +++ b/psycopg/connection_int.c @@ -642,6 +642,7 @@ static int _conn_poll_connecting(connectionObject *self) { int res = PSYCO_POLL_ERROR; + const char *msg; Dprintf("conn_poll: poll connecting"); switch (PQconnectPoll(self->pgconn)) { @@ -656,7 +657,11 @@ _conn_poll_connecting(connectionObject *self) break; case PGRES_POLLING_FAILED: case PGRES_POLLING_ACTIVE: - PyErr_SetString(OperationalError, "asynchronous connection failed"); + msg = PQerrorMessage(self->pgconn); + if (!(msg && *msg)) { + msg = "asynchronous connection failed"; + } + PyErr_SetString(OperationalError, msg); res = PSYCO_POLL_ERROR; break; } diff --git a/tests/test_async.py b/tests/test_async.py index 08113c4f..61a1ece5 100755 --- a/tests/test_async.py +++ b/tests/test_async.py @@ -448,6 +448,16 @@ class AsyncTests(unittest.TestCase): self.wait(self.conn) self.assertEqual(cur.fetchone(), (42,)) + def test_async_connection_error_message(self): + try: + cnn = psycopg2.connect('dbname=thisdatabasedoesntexist', async=True) + self.wait(cnn) + except psycopg2.Error, e: + self.assertNotEqual(str(e), "asynchronous connection failed", + "connection error reason lost") + else: + self.fail("no exception raised") + def test_suite(): return unittest.TestLoader().loadTestsFromName(__name__)