loco-rs/loco · error

db connection should success

Error message

db connection should success

What it means

In Loco's test support, the Postgres `init_db` connects to the server using a root/admin connection string before creating the per-test database. `Pool::connect` failing (server unreachable, bad credentials, wrong port) triggers `.expect("db connection should success")`, panicking the test-support boot with no retry.

Solutions

  1. Verify the test DB connection string (host, port, user, password) and start Postgres: `docker run -p 5432:5432 -e POSTGRES_PASSWORD=... postgres` or `docker compose up -d db`
  2. Check the env var feeding the test config (`LOCO_CONFIG_DATABASE_URI` / test.yaml `database.uri`) resolves correctly in the test environment
  3. Add a Postgres service container in CI before the test step and wait for readiness (healthcheck/pg_isready)
  4. Confirm the root user has CREATEDB privilege so subsequent schema creation can succeed

Example fix

// before (test.yaml)
database:
  uri: "postgres://loco:secret@localhost:5433/loco_test"
// after — match the running server
# psql -h localhost -p 5432 -U postgres -c 'select 1'  # verify first
database:
  uri: "postgres://postgres:postgres@localhost:5432/loco_test"
Defensive patterns

Strategy: retry

Validate before calling

// Readiness probe before running tests
let ok = tokio::net::TcpStream::connect("127.0.0.1:5432").await.is_ok();
assert!(ok, "Postgres not reachable on 127.0.0.1:5432");
// Or: pg_isready -h localhost -p 5432

Try / catch

// Wrap test-support boot and fail with a readable message
match std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
    // boot_test / request::<App,_,_> setup
})) {
    Ok(v) => v,
    Err(_) => panic!("test DB unreachable — is Postgres running and is the root URI correct?"),
}

Prevention

When it happens

Trigger: Running tests when the Postgres server at the configured `root_connection_string` is down, the URL has a wrong host/port/user/password, the database does not accept the root user, or networking/DNS in CI cannot reach the DB.

Common situations: Forgetting to start Postgres locally (`docker compose up db`), wrong `DATABASE_URL`-style test env var, CI runner without a Postgres service container, auth errors like `password authentication failed for user postgres`.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


AI-assisted analysis of loco-rs/loco@23639d1e36 (2026-09-12). Data as JSON: /api/errors/c2b72d79d0305753. Report an issue: GitHub.

Appendix: source

Thrown at src/testing/db.rs:121

        Ok(Self {
            root_connection_string: root_url.to_string(),
            connection_string: test_url.to_string(),
            schema_name: test_schema_name,
        })
    }
}

impl TestSupport for PostgresTest {
    fn get_connection_str(&self) -> &str {
        &self.connection_string
    }

    fn init_db<'a>(&'a self) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
        Box::pin(async move {
            let pool = Pool::<Postgres>::connect(&self.root_connection_string)
                .await
                .expect("db connection should success");
            let query = format!("CREATE DATABASE {};", self.schema_name);

            sqlx::query(AssertSqlSafe(query))
                .execute(&pool)
                .await
                .expect("create DB schema");
        })
    }

    fn cleanup_db(&self) {
        let connection_string = self.root_connection_string.clone();
        let table_name = self.schema_name.clone();

        // Run the drop on a dedicated OS thread with its own runtime (not
        // `tokio::task::spawn_blocking`, which schedules onto the ambient
        // runtime and cannot be awaited from a sync/Drop context) and `.join()`
        // it so cleanup fully completes before `cleanup_db` returns. This is
        // safe to call from `Drop::drop` since nothing here is `.await`ed on

View on GitHub (pinned to 23639d1e36)