diff options
author | Greg Ward <gward@dyn.com> | 2016-06-28 18:03:05 -0400 |
---|---|---|
committer | Daniele Varrazzo <daniele.varrazzo@gmail.com> | 2017-03-14 12:14:00 +0000 |
commit | 12317557da20d84baf12054d8dfce11ba8976cb6 (patch) | |
tree | d3ece83aea87254583d665a8923ca1bd1bc706f7 | |
parent | b203a7c775c5f81f59c6b4205c3c33455ceeec3d (diff) | |
download | psycopg2-12317557da20d84baf12054d8dfce11ba8976cb6.tar.gz |
Always raise OperationalError when connection was closed externally.
From the DB-API (https://www.python.org/dev/peps/pep-0249/):
OperationalError
Exception raised for errors that are related to the database's
operation and not necessarily under the control of the programmer,
e.g. an unexpected disconnect occurs, [...]
Additionally, psycopg2 was inconsistent, at least in the async case:
depending on how the "connection closed" error was reported from the
kernel to libpq, it would sometimes raise OperationalError and
sometimes DatabaseError. Now it always raises OperationalError.
-rw-r--r-- | psycopg/pqpath.c | 10 | ||||
-rwxr-xr-x | tests/test_cursor.py | 2 |
2 files changed, 7 insertions, 5 deletions
diff --git a/psycopg/pqpath.c b/psycopg/pqpath.c index 222696b..f270ce8 100644 --- a/psycopg/pqpath.c +++ b/psycopg/pqpath.c @@ -179,8 +179,10 @@ pq_raise(connectionObject *conn, cursorObject *curs, PGresult **pgres) /* if the connection has somehow been broken, we mark the connection object as closed but requiring cleanup */ - if (conn->pgconn != NULL && PQstatus(conn->pgconn) == CONNECTION_BAD) + if (conn->pgconn != NULL && PQstatus(conn->pgconn) == CONNECTION_BAD) { conn->closed = 2; + exc = OperationalError; + } if (pgres == NULL && curs != NULL) pgres = &curs->pgres; @@ -214,9 +216,9 @@ pq_raise(connectionObject *conn, cursorObject *curs, PGresult **pgres) if (code != NULL) { exc = exception_from_sqlstate(code); } - else { - /* Fallback if there is no exception code (reported happening e.g. - * when the connection is closed). */ + else if (exc == NULL) { + /* Fallback if there is no exception code (unless we already + determined that the connection was closed). */ exc = DatabaseError; } diff --git a/tests/test_cursor.py b/tests/test_cursor.py index f9fc66c..98891ea 100755 --- a/tests/test_cursor.py +++ b/tests/test_cursor.py @@ -575,7 +575,7 @@ class CursorTests(ConnectingTestCase): cur.execute('select pg_terminate_backend(%s)', (pid1,)) time.sleep(0.001) - with self.assertRaises(psycopg2.DatabaseError): + with self.assertRaises(psycopg2.OperationalError): with victim_conn.cursor() as cur: cur.execute('select 1') wait_func(victim_conn) |