From 9a9eac86ca564a845bb750afd966e9f9f6e510f8 Mon Sep 17 00:00:00 2001 From: Dan Boros Date: Thu, 18 Dec 2025 09:02:51 -0700 Subject: [PATCH] Allow skipping the unreplayable body check --- request.go | 21 ++++++++++++++++++++- retry.go | 2 ++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/request.go b/request.go index d7695a32..8ee81e65 100644 --- a/request.go +++ b/request.go @@ -656,7 +656,10 @@ func (r *Request) Do(ctx ...context.Context) *Response { if r.error != nil { return r.newErrorResponse(r.error) } - if r.retryOption != nil && r.retryOption.MaxRetries != 0 && r.unReplayableBody != nil { // retryable request should not have unreplayable Body + if r.retryOption != nil && + r.retryOption.MaxRetries != 0 && + !r.retryOption.SkipCheckingBody && + r.unReplayableBody != nil { // retryable request should not have unreplayable Body return r.newErrorResponse(errRetryableWithUnReplayableBody) } resp, _ := r.do() @@ -1229,6 +1232,22 @@ func (r *Request) AddRetryCondition(condition RetryConditionFunc) *Request { return r } +// EnableSkipCheckingBody skips checking for an unreplayable body to allow the +// caller to handle the body explicitly on retries. +func (r *Request) EnableSkipCheckingBody() *Request { + ro := r.getRetryOption() + ro.SkipCheckingBody = true + return r +} + +// DisableSkipCheckingBody enables checking for an unreplayable body to protect +// the caller from mishandling the body. +func (r *Request) DisableSkipCheckingBody() *Request { + ro := r.getRetryOption() + ro.SkipCheckingBody = false + return r +} + // SetClient change the client of request dynamically. func (r *Request) SetClient(client *Client) *Request { if client != nil { diff --git a/retry.go b/retry.go index fa67c843..f4a57a1e 100644 --- a/retry.go +++ b/retry.go @@ -43,6 +43,7 @@ type retryOption struct { GetRetryInterval GetRetryIntervalFunc RetryConditions []RetryConditionFunc RetryHooks []RetryHookFunc + SkipCheckingBody bool } func (ro *retryOption) Clone() *retryOption { @@ -52,6 +53,7 @@ func (ro *retryOption) Clone() *retryOption { o := &retryOption{ MaxRetries: ro.MaxRetries, GetRetryInterval: ro.GetRetryInterval, + SkipCheckingBody: ro.SkipCheckingBody, } o.RetryConditions = append(o.RetryConditions, ro.RetryConditions...) o.RetryHooks = append(o.RetryHooks, ro.RetryHooks...)