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

Failing to connect leads to ErrBadConn #1019

Closed
bouk opened this issue Oct 25, 2019 · 2 comments · Fixed by #1020
Closed

Failing to connect leads to ErrBadConn #1019

bouk opened this issue Oct 25, 2019 · 2 comments · Fixed by #1020

Comments

@bouk
Copy link
Contributor

bouk commented Oct 25, 2019

Issue description

I'm trying to upgrade from 1.4.1 to the latest master, but because of #867 any failed attempt to connect results in ErrBadConn, instead of the underlying error. I don't think using the builtin database/sql bad connection handling as a retry mechanism is a good idea, as it makes it impossible to handle connection errors.

ErrBadConn is never supposed to bubble up to the user of database/sql, the doc of ErrBadConn says:

ErrBadConn should be returned by a driver to signal to the sql package that a driver.Conn is in a bad state (such as the server having earlier closed the connection) and the sql package should retry on a new connection.

This says that it should only be used for connection that are in a bad state, not for initial connections.

Example code

package main

import (
        "context"
        "database/sql"
        _ "github.com/go-sql-driver/mysql"
)

func main() {
        // 1.1.1.1:1341 here is just an example address that will time out
        db, _ := sql.Open("mysql", "mysql://root@tcp(1.1.1.1:1341)/db?timeout=1s")
        _, err = db.Conn(context.Background())
        if err != nil {
                panic(err)
        }
} 

The output of this is:

$ go run main.go
[mysql] 2019/10/25 09:20:47 connector.go:48: net.Error from Dial()': dial tcp 1.1.1.1:1341: i/o timeout
[mysql] 2019/10/25 09:20:48 connector.go:48: net.Error from Dial()': dial tcp 1.1.1.1:1341: i/o timeout
[mysql] 2019/10/25 09:20:49 connector.go:48: net.Error from Dial()': dial tcp 1.1.1.1:1341: i/o timeout
panic: driver: bad connection

goroutine 1 [running]:
main.main()
        /home/bouke/cthulhu/docode/src/do/bla/main.go:17 +0xbc
exit status 2

When I expect it to be

$ go run main.go
panic: dial tcp 1.1.1.1:1341: i/o timeout

goroutine 1 [running]:
main.main()
        /home/bouke/cthulhu/docode/src/do/bla/main.go:17 +0xbc
exit status 2

Configuration

Driver version (or git SHA):

6ea7374bc1b0

Go version: run go version in your console

1.13.1

@bouk
Copy link
Contributor Author

bouk commented Oct 25, 2019

cc @tjenkinson

@tjenkinson
Copy link
Contributor

This says that it should only be used for connection that are in a bad state, not for initial connections.

Do you know if there's a way of knowing if the call in the driver is from the initial database/sql.Open() call?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants