]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Handle "SSL SYSCALL error: Success" in psycopg2
authorDavid H. Irving <david.irving@noirlab.edu>
Sun, 23 Jun 2024 09:37:24 +0000 (05:37 -0400)
committerFederico Caselli <cfederico87@gmail.com>
Tue, 25 Jun 2024 20:15:07 +0000 (22:15 +0200)
Added "SSL SYSCALL error: Success" to the list of exceptions
that are considered a "disconnect" in psycopg2.

Fixes: #11522
Closes: #11523
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/11523
Pull-request-sha: 63ad54e49dc3daa459caa29da8cffcb3e47a3f8c

Change-Id: I0db49d5c4db418a8e634f5370c76b99aaa3d3af6

doc/build/changelog/unreleased_20/11522.rst [new file with mode: 0644]
lib/sqlalchemy/dialects/postgresql/psycopg2.py
test/dialect/postgresql/test_dialect.py

diff --git a/doc/build/changelog/unreleased_20/11522.rst b/doc/build/changelog/unreleased_20/11522.rst
new file mode 100644 (file)
index 0000000..279197a
--- /dev/null
@@ -0,0 +1,7 @@
+.. change::
+    :tags: bug, postgresql
+    :tickets: 11522
+
+    It is now considered a pool-invalidating disconnect event when psycopg2
+    throws an "SSL SYSCALL error: Success" error message, which can occur when
+    the SSL connection to Postgres is terminated abnormally.
\ No newline at end of file
index 6c492a5b2501fd12d1db344b53a69ce4f04175f0..fc05aca9078de957ced74888ded691eb9511a108 100644 (file)
@@ -844,33 +844,43 @@ class PGDialect_psycopg2(_PGDialect_common_psycopg):
             # checks based on strings.  in the case that .closed
             # didn't cut it, fall back onto these.
             str_e = str(e).partition("\n")[0]
-            for msg in [
-                # these error messages from libpq: interfaces/libpq/fe-misc.c
-                # and interfaces/libpq/fe-secure.c.
-                "terminating connection",
-                "closed the connection",
-                "connection not open",
-                "could not receive data from server",
-                "could not send data to server",
-                # psycopg2 client errors, psycopg2/connection.h,
-                # psycopg2/cursor.h
-                "connection already closed",
-                "cursor already closed",
-                # not sure where this path is originally from, it may
-                # be obsolete.   It really says "losed", not "closed".
-                "losed the connection unexpectedly",
-                # these can occur in newer SSL
-                "connection has been closed unexpectedly",
-                "SSL error: decryption failed or bad record mac",
-                "SSL SYSCALL error: Bad file descriptor",
-                "SSL SYSCALL error: EOF detected",
-                "SSL SYSCALL error: Operation timed out",
-                "SSL SYSCALL error: Bad address",
-            ]:
+            for msg in self._is_disconnect_messages:
                 idx = str_e.find(msg)
                 if idx >= 0 and '"' not in str_e[:idx]:
                     return True
         return False
 
+    @util.memoized_property
+    def _is_disconnect_messages(self):
+        return (
+            # these error messages from libpq: interfaces/libpq/fe-misc.c
+            # and interfaces/libpq/fe-secure.c.
+            "terminating connection",
+            "closed the connection",
+            "connection not open",
+            "could not receive data from server",
+            "could not send data to server",
+            # psycopg2 client errors, psycopg2/connection.h,
+            # psycopg2/cursor.h
+            "connection already closed",
+            "cursor already closed",
+            # not sure where this path is originally from, it may
+            # be obsolete.   It really says "losed", not "closed".
+            "losed the connection unexpectedly",
+            # these can occur in newer SSL
+            "connection has been closed unexpectedly",
+            "SSL error: decryption failed or bad record mac",
+            "SSL SYSCALL error: Bad file descriptor",
+            "SSL SYSCALL error: EOF detected",
+            "SSL SYSCALL error: Operation timed out",
+            "SSL SYSCALL error: Bad address",
+            # This can occur in OpenSSL 1 when an unexpected EOF occurs.
+            # https://www.openssl.org/docs/man1.1.1/man3/SSL_get_error.html#BUGS
+            # It may also occur in newer OpenSSL for a non-recoverable I/O
+            # error as a result of a system call that does not set 'errno'
+            # in libc.
+            "SSL SYSCALL error: Success",
+        )
+
 
 dialect = PGDialect_psycopg2
index eae1b55d6e99c79b69c53e85283ec4c8a98c115c..3f55c085fb4cfaa96a68a088d75c7e183bd38382 100644 (file)
@@ -365,6 +365,7 @@ $$ LANGUAGE plpgsql;"""
             "SSL SYSCALL error: EOF detected",
             "SSL SYSCALL error: Operation timed out",
             "SSL SYSCALL error: Bad address",
+            "SSL SYSCALL error: Success",
         ]:
             eq_(dialect.is_disconnect(Error(error), None, None), True)