From 25eb21e556c442fe806c846b3936e6e7fa46f4ef Mon Sep 17 00:00:00 2001 From: Danny Hermes Date: Thu, 19 Nov 2020 12:38:16 -0600 Subject: [PATCH] Mark `net.Conn` failed writes as recoverable when 0 bytes were written. --- conn.go | 13 ++++++++++++- error.go | 3 +++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/conn.go b/conn.go index f313c149..0d96600e 100644 --- a/conn.go +++ b/conn.go @@ -891,9 +891,20 @@ func (cn *conn) Exec(query string, args []driver.Value) (res driver.Result, err return r, err } +type safeRetryError struct { + Err error +} + +func (se *safeRetryError) Error() string { + return se.Err.Error() +} + func (cn *conn) send(m *writeBuf) { - _, err := cn.c.Write(m.wrap()) + n, err := cn.c.Write(m.wrap()) if err != nil { + if n == 0 { + err = &safeRetryError{Err: err} + } panic(err) } } diff --git a/error.go b/error.go index 3d66ba7c..a227e083 100644 --- a/error.go +++ b/error.go @@ -495,6 +495,9 @@ func (cn *conn) errRecover(err *error) { case *net.OpError: cn.bad = true *err = v + case *safeRetryError: + cn.bad = true + *err = driver.ErrBadConn case error: if v == io.EOF || v.(error).Error() == "remote error: handshake failure" { *err = driver.ErrBadConn