package redis
import (
"context"
"io"
"net"
"strings"
"github.com/redis/go-redis/v9/internal/pool"
"github.com/redis/go-redis/v9/internal/proto"
)
var ErrClosed = pool .ErrClosed
func HasErrorPrefix (err error , prefix string ) bool {
err , ok := err .(Error )
if !ok {
return false
}
msg := err .Error()
msg = strings .TrimPrefix (msg , "ERR " )
return strings .HasPrefix (msg , prefix )
}
type Error interface {
error
RedisError()
}
var _ Error = proto .RedisError ("" )
func shouldRetry(err error , retryTimeout bool ) bool {
switch err {
case io .EOF , io .ErrUnexpectedEOF :
return true
case nil , context .Canceled , context .DeadlineExceeded :
return false
}
if v , ok := err .(timeoutError ); ok {
if v .Timeout () {
return retryTimeout
}
return true
}
s := err .Error()
if s == "ERR max number of clients reached" {
return true
}
if strings .HasPrefix (s , "LOADING " ) {
return true
}
if strings .HasPrefix (s , "READONLY " ) {
return true
}
if strings .HasPrefix (s , "CLUSTERDOWN " ) {
return true
}
if strings .HasPrefix (s , "TRYAGAIN " ) {
return true
}
return false
}
func isRedisError(err error ) bool {
_ , ok := err .(proto .RedisError )
return ok
}
func isBadConn(err error , allowTimeout bool , addr string ) bool {
switch err {
case nil :
return false
case context .Canceled , context .DeadlineExceeded :
return true
}
if isRedisError (err ) {
switch {
case isReadOnlyError (err ):
return true
case isMovedSameConnAddr (err , addr ):
return true
default :
return false
}
}
if allowTimeout {
if netErr , ok := err .(net .Error ); ok && netErr .Timeout () {
return false
}
}
return true
}
func isMovedError(err error ) (moved bool , ask bool , addr string ) {
if !isRedisError (err ) {
return
}
s := err .Error()
switch {
case strings .HasPrefix (s , "MOVED " ):
moved = true
case strings .HasPrefix (s , "ASK " ):
ask = true
default :
return
}
ind := strings .LastIndex (s , " " )
if ind == -1 {
return false , false , ""
}
addr = s [ind +1 :]
return
}
func isLoadingError(err error ) bool {
return strings .HasPrefix (err .Error(), "LOADING " )
}
func isReadOnlyError(err error ) bool {
return strings .HasPrefix (err .Error(), "READONLY " )
}
func isMovedSameConnAddr(err error , addr string ) bool {
redisError := err .Error()
if !strings .HasPrefix (redisError , "MOVED " ) {
return false
}
return strings .HasSuffix (redisError , " " +addr )
}
type timeoutError interface {
Timeout() bool
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .