diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fcd90d53..5f0f3d77e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ Versioning](http://semver.org/spec/v2.0.0.html) except to the first release. - Type() method to the Request interface (#158) - Enumeration types for RLimitAction/iterators (#158) - IsNullable flag for Field (#302) +- Meaningful errors for error descriptions for a read/write socket + errors (#129) ### Changed diff --git a/connection.go b/connection.go index 367cf9640..37de22e82 100644 --- a/connection.go +++ b/connection.go @@ -789,6 +789,10 @@ func (conn *Connection) writer(w writeFlusher, c Conn) { runtime.Gosched() if len(conn.dirtyShard) == 0 { if err := w.Flush(); err != nil { + err = ClientError{ + ErrIoError, + fmt.Sprintf("failed to flush data to the connection: %s", err), + } conn.reconnect(err, c) return } @@ -812,6 +816,10 @@ func (conn *Connection) writer(w writeFlusher, c Conn) { continue } if _, err := w.Write(packet.b); err != nil { + err = ClientError{ + ErrIoError, + fmt.Sprintf("failed to write data to the connection: %s", err), + } conn.reconnect(err, c) return } @@ -868,12 +876,20 @@ func (conn *Connection) reader(r io.Reader, c Conn) { for atomic.LoadUint32(&conn.state) != connClosed { respBytes, err := read(r, conn.lenbuf[:]) if err != nil { + err = ClientError{ + ErrIoError, + fmt.Sprintf("failed to read data from the connection: %s", err), + } conn.reconnect(err, c) return } resp := &Response{buf: smallBuf{b: respBytes}} err = resp.decodeHeader(conn.dec) if err != nil { + err = ClientError{ + ErrProtocolError, + fmt.Sprintf("failed to decode IPROTO header: %s", err), + } conn.reconnect(err, c) return } @@ -883,6 +899,10 @@ func (conn *Connection) reader(r io.Reader, c Conn) { if event, err := readWatchEvent(&resp.buf); err == nil { events <- event } else { + err = ClientError{ + ErrProtocolError, + fmt.Sprintf("failed to decode IPROTO_EVENT: %s", err), + } conn.opts.Logger.Report(LogWatchEventReadFailed, conn, err) } continue diff --git a/errors.go b/errors.go index ab40e4f63..60f71a2b1 100644 --- a/errors.go +++ b/errors.go @@ -45,7 +45,7 @@ func (clierr ClientError) Error() string { // - request is aborted due to rate limit func (clierr ClientError) Temporary() bool { switch clierr.Code { - case ErrConnectionNotReady, ErrTimeouted, ErrRateLimited: + case ErrConnectionNotReady, ErrTimeouted, ErrRateLimited, ErrIoError: return true default: return false @@ -60,4 +60,5 @@ const ( ErrTimeouted = 0x4000 + iota ErrRateLimited = 0x4000 + iota ErrConnectionShutdown = 0x4000 + iota + ErrIoError = 0x4000 + iota )