fix(mysql): retry without ssl on TLS close

This commit is contained in:
t8y2
2026-05-20 10:42:20 +08:00
parent 65b51e6c17
commit ea19a24ec6
+18 -1
View File
@@ -170,7 +170,7 @@ pub async fn connect(url: &str) -> Result<MySqlPool, String> {
.await;
if let Err(ref e) = result {
if e.contains("HandshakeFailure") || e.contains("handshake") {
if mysql_error_should_retry_without_ssl(e) {
if let Some(fallback_url) = ssl_fallback_url(url) {
log::info!("SSL handshake failed, retrying with ssl-mode=disabled");
return super::with_connection_timeout("MySQL", async {
@@ -190,6 +190,14 @@ pub async fn connect(url: &str) -> Result<MySqlPool, String> {
result
}
fn mysql_error_should_retry_without_ssl(error: &str) -> bool {
let error = error.to_ascii_lowercase();
error.contains("handshakefailure")
|| error.contains("handshake")
|| error.contains("tls connection")
|| error.contains("server closed session")
}
fn ssl_fallback_url(url: &str) -> Option<String> {
if url.contains("ssl-mode=preferred") {
Some(url.replace("ssl-mode=preferred", "ssl-mode=disabled"))
@@ -592,4 +600,13 @@ mod tests {
assert!(!requires_text_protocol_query("SHOW TABLES"));
assert!(!requires_text_protocol_query("SELECT * FROM users"));
}
#[test]
fn mysql_tls_session_close_errors_retry_without_ssl() {
let error = "MySQL connection failed: error communicating with database: \
encountered error while attempting to establish a TLS connection: \
server closed session with no notification";
assert!(mysql_error_should_retry_without_ssl(error));
}
}