pgx
pgx copied to clipboard
Wrong host in ConnectError
Describe the bug
When a connection string contains multiple hosts, the Config.Host field is populated with the first host, while the remaining hosts are treated as FallbackConfigs. The connect function, which accepts both Config and FallbackConfig to establish a connection, uses the Host and Port from the FallbackConfig.
https://github.com/jackc/pgx/blob/da6f2c98f2664b215b40b1606551fdfcc7f3ea5c/pgconn/pgconn.go#L283
However, in the event of a connection error, the default Config is used, leading to a mismatch between the error message (which contains the IP address of the host we attempted to connect to) and the Host and Port from a different host.
https://github.com/jackc/pgx/blob/da6f2c98f2664b215b40b1606551fdfcc7f3ea5c/pgconn/pgconn.go#L286
To Reproduce Steps to reproduce the behavior:
package main
import (
"context"
"log"
"github.com/jackc/pgx/v5"
)
const url = "postgresql://user:password@localhost:1234,127.0.0.1:5678/database"
func main() {
conn, err := pgx.Connect(context.Background(), url)
if err != nil {
log.Fatal(err)
}
defer conn.Close(context.Background())
}
Expected behavior The error message should match the host we attempted to connect to. Possible outcome are
host=localhost ... dial tcp 127.0.0.1:1234host=127.0.0.1 ... dial tcp 127.0.0.1:5678
Actual behavior The error message contains a mismatched host and port
2024/03/06 11:13:07 failed to connect to `host=localhost user=user database=database`: dial error (dial tcp 127.0.0.1:5678: connect: connection refused)
exit status 1
Additional context
It would be more informative to return an error group containing connection errors for all attempted hosts. This would be particularly useful when target_session_attrs=primary is used and a connection to the primary cannot be established. In this case we can get a useless server is in standby mode while connecting to the other node.
It would be more informative to return an error group containing connection errors for all attempted hosts.
As of Go 1.20 we now have a better way of returning multiple errors. That's a reasonable change. 👍
I've added multiple error returns for connection failures in 8db971660e43a944c777d5e4fcfcb7885acb7566.
For example, the following connection string:
host=localhost,127.0.0.1,foo.invalid port=1,2,3
Will now return an error like the following:
failed to connect to `user=postgres database=pgx_test`:
lookup foo.invalid: no such host
[::1]:1 (localhost): dial error: dial tcp [::1]:1: connect: connection refused
127.0.0.1:1 (localhost): dial error: dial tcp 127.0.0.1:1: connect: connection refused
127.0.0.1:2 (127.0.0.1): dial error: dial tcp 127.0.0.1:2: connect: connection refused