-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Description
Description
Actual Behavior:
The code waits for the duration specified in .acquire_timeout() (10 seconds in this example) and then fails with sqlx::Error::PoolTimedOut.
Attempting to connect...
Failed to create pool: PoolTimedOut
Error is indeed PoolTimedOut.
Expected Behavior:
I would expect the connection attempt to fail much faster with an error that indicates a problem establishing the initial TCP connection, such as:
- A database-specific connection error (like "Connection Refused").
- A generic I/O error (
sqlx::Error::Iowrapping astd::io::Error) indicating a network issue or a timeout at the OS/driver level for establishing the connection itself.
Issue/Question:
- Why is
sqlx::Error::PoolTimedOutreturned in this scenario? This error typically suggests that the pool is full and no connection could be acquired within the timeout, not that the initial connection to the database server failed. - It seems counter-intuitive that
acquire_timeoutcontrols the timeout for the initial connection establishment when the server is down. My understanding is thatacquire_timeoutshould apply when waiting for an available connection from an already functioning pool.
Suggestion:
It appears that in sqlx 0.8, there isn't a distinct way to set a timeout specifically for the TCP connection phase independent of the pool acquisition timeout. This leads to confusing error reporting when the database is unreachable.
Would it be possible (or perhaps it was intended differently?) to have a separate timeout mechanism for the initial connection attempts? Perhaps a connect_timeout option (maybe configurable via the URL string if not via a builder method in this version?) that would result in a more accurate Io or database-specific error when the server doesn't respond within that initial period? This would make debugging connection issues more straightforward.
Thank you
Reproduction steps
- Ensure the target MySQL server (e.g.,
localhost:3306) is shut down or inaccessible. - Run the following code:
use sqlx::mysql::MySqlPoolOptions;
use std::time::Duration;
#[tokio::main]
async fn main() {
println!("Attempting to connect...");
let pool_result = MySqlPoolOptions::new()
// Set a relatively long acquire_timeout
.acquire_timeout(Duration::from_secs(10))
// Attempt to connect to the downed server
.connect("mysql://root:@localhost:3306/non_existent_db") // Added user/db for typical URL
.await;
match pool_result {
Ok(_) => {
println!("Pool created successfully (unexpected!)");
}
Err(e) => {
// The error received is PoolTimedOut
eprintln!("Failed to create pool: {:?}", e);
// Example check:
if matches!(e, sqlx::Error::PoolTimedOut) {
eprintln!("Error is indeed PoolTimedOut.");
} else {
eprintln!("Error is something else: {}", e);
}
}
}
}SQLx version
0.8.3
Enabled SQLx features
"runtime-tokio", "mysql", "derive", "macros"
Database server and version
MySQL
Operating system
MacOS
Rust version
rustc 1.85.1 (4eb161250 2025-03-15)