You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

89 lines
1.5 KiB

  1. package internal
  2. import (
  3. "io"
  4. "net"
  5. "strings"
  6. "github.com/go-redis/redis/internal/proto"
  7. )
  8. func IsRetryableError(err error, retryTimeout bool) bool {
  9. if err == nil {
  10. return false
  11. }
  12. if err == io.EOF {
  13. return true
  14. }
  15. if netErr, ok := err.(net.Error); ok {
  16. if netErr.Timeout() {
  17. return retryTimeout
  18. }
  19. return true
  20. }
  21. s := err.Error()
  22. if s == "ERR max number of clients reached" {
  23. return true
  24. }
  25. if strings.HasPrefix(s, "LOADING ") {
  26. return true
  27. }
  28. if strings.HasPrefix(s, "READONLY ") {
  29. return true
  30. }
  31. if strings.HasPrefix(s, "CLUSTERDOWN ") {
  32. return true
  33. }
  34. return false
  35. }
  36. func IsRedisError(err error) bool {
  37. _, ok := err.(proto.RedisError)
  38. return ok
  39. }
  40. func IsBadConn(err error, allowTimeout bool) bool {
  41. if err == nil {
  42. return false
  43. }
  44. if IsRedisError(err) {
  45. // #790
  46. return IsReadOnlyError(err)
  47. }
  48. if allowTimeout {
  49. if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
  50. return false
  51. }
  52. }
  53. return true
  54. }
  55. func IsMovedError(err error) (moved bool, ask bool, addr string) {
  56. if !IsRedisError(err) {
  57. return
  58. }
  59. s := err.Error()
  60. if strings.HasPrefix(s, "MOVED ") {
  61. moved = true
  62. } else if strings.HasPrefix(s, "ASK ") {
  63. ask = true
  64. } else {
  65. return
  66. }
  67. ind := strings.LastIndex(s, " ")
  68. if ind == -1 {
  69. return false, false, ""
  70. }
  71. addr = s[ind+1:]
  72. return
  73. }
  74. func IsLoadingError(err error) bool {
  75. return strings.HasPrefix(err.Error(), "LOADING ")
  76. }
  77. func IsReadOnlyError(err error) bool {
  78. return strings.HasPrefix(err.Error(), "READONLY ")
  79. }