fix(logger): add logging for request retries

This commit is contained in:
2026-09-21 22:19:00 +03:30
parent c6e2ce7fd5
commit 8bea266f03
3 changed files with 147 additions and 0 deletions

View File

@@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"io"
"log/slog"
"net"
"net/http"
"time"
@@ -27,6 +28,7 @@ type Client struct {
tokenProvider TokenProvider
maxRetries int
retryWait func(ctx context.Context, delay time.Duration) bool
logger *slog.Logger
}
var _ service.CardToIBANClient = (*Client)(nil)
@@ -41,20 +43,34 @@ func NewClient(
endpointURL string,
tokenProvider TokenProvider,
maxRetries int,
loggers ...*slog.Logger,
) *Client {
if maxRetries < 0 {
maxRetries = 0
}
var logger *slog.Logger
if len(loggers) > 0 && loggers[0] != nil {
logger = loggers[0]
}
return &Client{
httpClient: httpClient,
endpointURL: endpointURL,
tokenProvider: tokenProvider,
maxRetries: maxRetries,
retryWait: waitForRetry,
logger: logger,
}
}
func (c *Client) log() *slog.Logger {
if c.logger != nil {
return c.logger
}
return slog.New(slog.NewTextHandler(io.Discard, nil))
}
func isRetryable(err error) bool {
return errors.Is(err, ErrTimeout) ||
errors.Is(err, ErrUnavailable)
@@ -105,6 +121,22 @@ func (c *Client) Convert(
}
for attempt := 0; attempt <= c.maxRetries; attempt++ {
if attempt > 0 {
c.log().InfoContext(
ctx,
fmt.Sprintf("[RETRY] zarinhub request attempt %d", attempt),
"is_retry", true,
"retry_count", attempt,
)
} else {
c.log().InfoContext(
ctx,
"[INITIAL] zarinhub request",
"is_retry", false,
"retry_count", 0,
)
}
result, err = c.convertOnce(
ctx,
cardNumber,
@@ -121,6 +153,15 @@ func (c *Client) Convert(
// We already used all configured retries.
if attempt == c.maxRetries {
if attempt > 0 {
c.log().ErrorContext(
ctx,
"[RETRY] zarinhub request failed: all retries exhausted",
"is_retry", true,
"retry_count", attempt,
"error", err,
)
}
return result, err
}
@@ -133,6 +174,14 @@ func (c *Client) Convert(
}
delay := retryDelay(attempt)
c.log().WarnContext(
ctx,
fmt.Sprintf("[RETRY] zarinhub request failed, retrying in %v (retry %d)", delay, attempt+1),
"is_retry", true,
"next_retry", attempt + 1,
"delay_ms", delay.Milliseconds(),
"error", err,
)
if !waitFn(ctx, delay) {
if errors.Is(ctx.Err(), context.Canceled) {