Add another exception case to Firebird' is_disconnect()

Issue #1646 resolved
Former user created an issue

On Firebird (from Fedora repo, firebird-2.1.3.18185.0-2.fc10.i386) when Classic Server process is killed during transaction, I've got ProgrammingError raised:

2009-12-25 13:23:20,453 INFO sqlalchemy.engine.base.Engine.0x...1db0 SELECT gen_id("GEN_NUMBER", 1) FROM rdb$database
2009-12-25 13:23:20,453 INFO sqlalchemy.engine.base.Engine.0x...1db0 None
(ProgrammingError) (-902, 'isc_dsql_prepare: \n  Unable to complete network request to host "192.168.1.2".\n  Error reading data from the connection.

and trying to rollback right after that:

2009-12-25 13:24:58,375 INFO sqlalchemy.engine.base.Engine.0x...1db0 ROLLBACK
OperationalError: (OperationalError) (-902, 'rollback: \n  Unable to complete network request to host "192.168.1.2".\n  Error writing data to the connection.)

Next transactions don't work:

Can't reconnect until invalid transaction is rolled back

This helps:

397c397
<         if isinstance(e, self.dbapi.OperationalError):
---
>         if isinstance(e, (self.dbapi.OperationalError, self.dbapi.ProgrammingError)):

Comments (14)

  1. Lele Gaifax

    Your change seems to break the other cases. Maybe the following is an equivalent-but-safer fix? I cannot figure out a proper test for this though.

    Index: lib/sqlalchemy/databases/firebird.py

    --- lib/sqlalchemy/databases/firebird.py (revisione 6566) +++ lib/sqlalchemy/databases/firebird.py (copia locale) @@ -394,11 +394,10 @@ return False

     def is_disconnect(self, e):
    
    • if isinstance(e, self.dbapi.OperationalError):
    • return 'Unable to complete network request to host' in str(e)
    • elif isinstance(e, self.dbapi.ProgrammingError):
    • if isinstance(e, (self.dbapi.OperationalError, self.dbapi.ProgrammingError)): msg = str(e)
    • return ('Invalid connection state' in msg or
    • return ('Unable to complete network request to host' in msg or
    • 'Invalid connection state' in msg or 'Invalid cursor state' in msg) else: return False
  2. Lele Gaifax

    Ouch, sorry, mouse slipped... :)

    Index: lib/sqlalchemy/databases/firebird.py
    ===================================================================
    --- lib/sqlalchemy/databases/firebird.py        (revisione 6566)
    +++ lib/sqlalchemy/databases/firebird.py        (copia locale)
    @@ -394,11 +394,10 @@
                 return False
    
         def is_disconnect(self, e):
    -        if isinstance(e, self.dbapi.OperationalError):
    -            return 'Unable to complete network request to host' in str(e)
    -        elif isinstance(e, self.dbapi.ProgrammingError):
    +        if isinstance(e, (self.dbapi.OperationalError, self.dbapi.ProgrammingError)):
                 msg = str(e)
    -            return ('Invalid connection state' in msg or
    +            return ('Unable to complete network request to host' in msg or
    +                    'Invalid connection state' in msg or
                         'Invalid cursor state' in msg)
             else:
                 return False
    
  3. Mike Bayer repo owner

    i think 535a4a77bf2415a292a6aa818df7bb3958569f67 is part of the commit here, would like it for 0.5 too + a note in CHANGES. a unit test here isn't super critical but it would be in test/dialect/test_firebird.py and it would generate appropriate ProgrammingError and OperationalError objects and just send them into testing.db.dialect.is_disconnect(), testing for true/false appropriately.

  4. Former user Account Deleted

    Sorry to bother but today I got this:

    ProgrammingError: (ProgrammingError) (-902, 'isc_dsql_execute: \n  connection shutdown')
    

    I guess - "connection shutdown" should be added too.

  5. Log in to comment