Skip to content

Commit

Permalink
GOCBC-477: Change isRetryableError to IsRetryableError
Browse files Browse the repository at this point in the history
Motivation
----------
Sometimes a user doesn't care about the error classification and
just wants to know if they should retry it.

Changes
-------
Change isRetryableError to IsRetryableError.

Change-Id: Ia126b05f69ec516031f43963a0aedbf590092e5a
Reviewed-on: http://review.couchbase.org/110208
Reviewed-by: Brett Lawson <brett19@gmail.com>
Tested-by: Charles Dixon <chvckd@gmail.com>
  • Loading branch information
chvck committed Jun 6, 2019
1 parent 23be34a commit a196091
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 13 deletions.
2 changes: 1 addition & 1 deletion cluster_analyticsquery.go
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ func (c *Cluster) analyticsQuery(ctx context.Context, traceCtx opentracing.SpanC
break
}

if !isRetryableError(err) || c.sb.AnalyticsRetryBehavior == nil || !c.sb.AnalyticsRetryBehavior.CanRetry(retries) {
if !IsRetryableError(err) || c.sb.AnalyticsRetryBehavior == nil || !c.sb.AnalyticsRetryBehavior.CanRetry(retries) {
break
}

Expand Down
4 changes: 2 additions & 2 deletions cluster_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ func (c *Cluster) query(ctx context.Context, traceCtx opentracing.SpanContext, s
break
}

if !isRetryableError(err) || c.sb.N1qlRetryBehavior == nil || !c.sb.N1qlRetryBehavior.CanRetry(retries) {
if !IsRetryableError(err) || c.sb.N1qlRetryBehavior == nil || !c.sb.N1qlRetryBehavior.CanRetry(retries) {
break
}

Expand Down Expand Up @@ -432,7 +432,7 @@ func (c *Cluster) doPreparedN1qlQuery(ctx context.Context, traceCtx opentracing.

// If we get error 4050, 4070 or 5000, we should attempt
// to re-prepare the statement immediately before failing.
if !isRetryableError(err) {
if !IsRetryableError(err) {
return nil, err
}
}
Expand Down
2 changes: 1 addition & 1 deletion cluster_searchquery.go
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ func (c *Cluster) searchQuery(ctx context.Context, traceCtx opentracing.SpanCont
break
}

if !isRetryableError(err) || c.sb.SearchRetryBehavior == nil || !c.sb.SearchRetryBehavior.CanRetry(retries) {
if !IsRetryableError(err) || c.sb.SearchRetryBehavior == nil || !c.sb.SearchRetryBehavior.CanRetry(retries) {
break
}

Expand Down
23 changes: 14 additions & 9 deletions error.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ func (err kvError) DurabilityError() bool {
err.StatusCode() == int(gocbcore.StatusDurabilityInvalidLevel)
}

func (err kvError) retryable() bool {
return err.TemporaryFailureError()
}

// DurabilityError occurs when an error occurs during performing durability operations.
type DurabilityError interface {
DurabilityError() bool
Expand Down Expand Up @@ -195,6 +199,16 @@ func IsTimeoutError(err error) bool {
}
}

// IsRetryableError indicates that the operation should be retried.
func IsRetryableError(err error) bool {
switch errType := errors.Cause(err).(type) {
case retryAbleError:
return errType.retryable()
default:
return false
}
}

// KV Specific Errors

// IsKeyValueError verifies whether or not the cause for an error is a KeyValueError.
Expand Down Expand Up @@ -889,15 +903,6 @@ func (e noResultsError) NoResultsError() bool {
return true
}

func isRetryableError(err error) bool {
switch errType := errors.Cause(err).(type) {
case retryAbleError:
return errType.retryable()
default:
return false
}
}

func maybeEnhanceKVErr(err error, key string, isInsertOp bool) error {
cause := errors.Cause(err)

Expand Down
38 changes: 38 additions & 0 deletions error_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,41 @@ func TestIsCasMismatchError(t *testing.T) {
t.Fatalf("Error should not have been cas mismatch")
}
}

func TestKVIsRetryable(t *testing.T) {
err := &gocbcore.KvError{
Code: gocbcore.StatusTmpFail,
}

enhancedErr := maybeEnhanceKVErr(err, "myfakekey", false)
if !IsRetryableError(enhancedErr) {
t.Fatalf("StatusTmpFail error should have been retryable")
}

err = &gocbcore.KvError{
Code: gocbcore.StatusOutOfMemory,
}

enhancedErr = maybeEnhanceKVErr(err, "myfakekey", false)
if !IsRetryableError(enhancedErr) {
t.Fatalf("StatusOutOfMemory error should have been retryable")
}

err = &gocbcore.KvError{
Code: gocbcore.StatusBusy,
}

enhancedErr = maybeEnhanceKVErr(err, "myfakekey", false)
if !IsRetryableError(enhancedErr) {
t.Fatalf("StatusBusy error should have been retryable")
}

err = &gocbcore.KvError{
Code: gocbcore.StatusTooBig,
}

enhancedErr = maybeEnhanceKVErr(err, "myfakekey", false)
if IsRetryableError(enhancedErr) {
t.Fatalf("StatusTooBig error should not have been retryable")
}
}

0 comments on commit a196091

Please sign in to comment.