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.
This commit is contained in:
Greg Ward 2016-06-28 18:03:05 -04:00
parent ac14957fbb
commit 53c1607644
2 changed files with 7 additions and 5 deletions

View File

@ -167,8 +167,10 @@ pq_raise(connectionObject *conn, cursorObject *curs, PGresult **pgres)
/* if the connection has somehow beed 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;
@ -202,9 +204,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;
}

View File

@ -527,7 +527,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)