mirror of
https://github.com/psycopg/psycopg2.git
synced 2024-11-22 08:56:34 +03:00
Don't try to close the server cursor in error state
`close()` is implicitly called by `__exit__()`, so an exit on error would run a query on a inerr connection, causing another exception hiding the original one. The fix is on `close()`, not on `__exit__()`, because the semantic of the latter is simply to call the former. Closes #262.
This commit is contained in:
parent
d6688b6689
commit
e3c6b46416
7
NEWS
7
NEWS
|
@ -1,6 +1,13 @@
|
|||
Current release
|
||||
---------------
|
||||
|
||||
What's new in psycopg 2.5.5
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- Named cursors used as context manager don't swallow the exception on exit
|
||||
(:ticket:`#262`).
|
||||
|
||||
|
||||
What's new in psycopg 2.5.4
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
|
|
@ -57,11 +57,25 @@ psyco_curs_close(cursorObject *self)
|
|||
|
||||
if (self->name != NULL) {
|
||||
char buffer[128];
|
||||
PGTransactionStatusType status;
|
||||
|
||||
if (self->conn) {
|
||||
status = PQtransactionStatus(self->conn->pgconn);
|
||||
}
|
||||
else {
|
||||
status = PQTRANS_UNKNOWN;
|
||||
}
|
||||
|
||||
if (!(status == PQTRANS_UNKNOWN || status == PQTRANS_INERROR)) {
|
||||
EXC_IF_NO_MARK(self);
|
||||
PyOS_snprintf(buffer, 127, "CLOSE \"%s\"", self->name);
|
||||
if (pq_execute(self, buffer, 0, 0, 1) == -1) return NULL;
|
||||
}
|
||||
else {
|
||||
Dprintf("skipping named curs close because tx status %d",
|
||||
(int)status);
|
||||
}
|
||||
}
|
||||
|
||||
self->closed = 1;
|
||||
Dprintf("psyco_curs_close: cursor at %p closed", self);
|
||||
|
|
|
@ -200,6 +200,18 @@ class WithCursorTestCase(WithTestCase):
|
|||
self.assert_(curs.closed)
|
||||
self.assert_(closes)
|
||||
|
||||
def test_exception_swallow(self):
|
||||
# bug #262: __exit__ calls cur.close() that hides the exception
|
||||
# with another error.
|
||||
try:
|
||||
with self.conn as conn:
|
||||
with conn.cursor('named') as cur:
|
||||
cur.execute("select 1/0")
|
||||
except psycopg2.DataError, e:
|
||||
self.assertEqual(e.pgcode, '22012')
|
||||
else:
|
||||
self.fail("where is my exception?")
|
||||
|
||||
|
||||
def test_suite():
|
||||
return unittest.TestLoader().loadTestsFromName(__name__)
|
||||
|
|
Loading…
Reference in New Issue
Block a user