Commit fafee743 authored by Anssi Kääriäinen's avatar Anssi Kääriäinen
Browse files

Removed try-except in django.db.close_connection()

The reason was that the except clause needed to remove a connection
from the django.db.connections dict, but other parts of Django do not
expect this to happen. In addition the except clause was silently
swallowing the exception messages.

Refs #19707, special thanks to Carl Meyer for pointing out that this
approach should be taken.
parent c4841b3d
Loading
Loading
Loading
Loading
+5 −8
Original line number Diff line number Diff line
@@ -45,14 +45,11 @@ def close_connection(**kwargs):
    # Avoid circular imports
    from django.db import transaction
    for conn in connections:
        try:
        # If an error happens here the connection will be left in broken
        # state. Once a good db connection is again available, the
        # connection state will be cleaned up.
        transaction.abort(conn)
        connections[conn].close()
        except Exception:
            # The connection's state is unknown, so it has to be
            # abandoned. This could happen for example if the network
            # connection has a failure.
            del connections[conn]
signals.request_finished.connect(close_connection)

# Register an event that resets connection.queries
+0 −3
Original line number Diff line number Diff line
@@ -99,9 +99,6 @@ class ConnectionHandler(object):
    def __setitem__(self, key, value):
        setattr(self._connections, key, value)

    def __delitem__(self, key):
        delattr(self._connections, key)

    def __iter__(self):
        return iter(self.databases)

+10 −8
Original line number Diff line number Diff line
@@ -548,9 +548,6 @@ class TransactionRequestTests(TransactionTestCase):
                     'This test will close the connection, in-memory '
                     'sqlite connections must not be closed.')
    def test_request_finished_failed_connection(self):
        # See comments in test_request_finished_db_state() for the self.client
        # usage.
        response = self.client.get('/')
        conn = connections[DEFAULT_DB_ALIAS]
        conn.enter_transaction_management()
        conn.managed(True)
@@ -560,9 +557,14 @@ class TransactionRequestTests(TransactionTestCase):
        def fail_horribly():
            raise Exception("Horrible failure!")
        conn._rollback = fail_horribly
        signals.request_finished.send(sender=response._handler_class)
        # As even rollback wasn't possible the connection wrapper itself was
        # abandoned. Accessing the connections[alias] will create a new
        # connection wrapper, whch must be different than the original one.
        self.assertIsNot(conn, connections[DEFAULT_DB_ALIAS])
        try:
            with self.assertRaises(Exception):
                signals.request_finished.send(sender=self.__class__)
            # The connection's state wasn't cleaned up
            self.assertTrue(len(connection.transaction_state), 1)
        finally:
            del conn._rollback
        # The connection will be cleaned on next request where the conn
        # works again.
        signals.request_finished.send(sender=self.__class__)
        self.assertEqual(len(connection.transaction_state), 0)