Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong host in ConnectError #1929

Closed
ndtretyak opened this issue Mar 6, 2024 · 2 comments
Closed

Wrong host in ConnectError #1929

ndtretyak opened this issue Mar 6, 2024 · 2 comments
Labels

Comments

@ndtretyak
Copy link

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.

network, address := NetworkAddress(fallbackConfig.Host, fallbackConfig.Port)

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.

return nil, &ConnectError{Config: config, msg: "dial error", err: normalizeTimeoutError(ctx, err)}

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:1234
  • host=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.

@ndtretyak ndtretyak added the bug label Mar 6, 2024
@jackc
Copy link
Owner

jackc commented Mar 9, 2024

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. 👍

jackc added a commit that referenced this issue May 11, 2024
A single Connect("connstring") may actually make multiple connection
requests due to TLS or HA configuration. Previously, when all attempts
failed only the last error was returned. This could be confusing.
Now details of all failed attempts are included.

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

#1929
@jackc
Copy link
Owner

jackc commented May 11, 2024

I've added multiple error returns for connection failures in 8db9716.

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

@jackc jackc closed this as completed May 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants