From 256957db5cbfc2a0328b2b153dbb8020cb9d1cfc Mon Sep 17 00:00:00 2001 From: Vitaliy Potyarkin Date: Tue, 5 Nov 2024 13:32:07 +0300 Subject: [PATCH] Expose rate limit errors in public API Signed-off-by: Vitaliy Potyarkin --- acme/api/internal/sender/sender.go | 8 ++++++++ acme/errors.go | 12 ++++++++++++ 2 files changed, 20 insertions(+) diff --git a/acme/api/internal/sender/sender.go b/acme/api/internal/sender/sender.go index 29cd7c9b..76c3af81 100644 --- a/acme/api/internal/sender/sender.go +++ b/acme/api/internal/sender/sender.go @@ -119,6 +119,14 @@ func (d *Doer) formatUserAgent() string { func checkError(req *http.Request, resp *http.Response) error { if resp.StatusCode >= http.StatusBadRequest { + if resp.StatusCode == http.StatusTooManyRequests { + return acme.TooManyRequestsError{ + StatusCode: resp.StatusCode, + Method: req.Method, + URL: req.URL, + } + } + body, err := io.ReadAll(resp.Body) if err != nil { return fmt.Errorf("%d :: %s :: %s :: %w", resp.StatusCode, req.Method, req.URL, err) diff --git a/acme/errors.go b/acme/errors.go index acaea5f6..57904607 100644 --- a/acme/errors.go +++ b/acme/errors.go @@ -2,6 +2,7 @@ package acme import ( "fmt" + "net/url" ) // Errors types. @@ -56,3 +57,14 @@ func (p ProblemDetails) Error() string { type NonceError struct { *ProblemDetails } + +// TooManyRequestsError represents API rate limit violations reported by server. +type TooManyRequestsError struct { + StatusCode int + Method string + URL *url.URL +} + +func (e TooManyRequestsError) Error() string { + return fmt.Sprintf("too many requests: HTTP %d: %s (%s)", e.StatusCode, e.URL, e.Method) +}