Skip to content

feat: expose Retry-After in Error - #44

Draft
gracehopper-vt wants to merge 1 commit into
masterfrom
feat/expose-retry-after
Draft

gracehopper-vt wants to merge 1 commit into
masterfrom
feat/expose-retry-after

Conversation

@gracehopper-vt

Copy link
Copy Markdown
Collaborator

Summary

The VirusTotal API is adding a Retry-After header to rate-limit / quota-exceeded responses (429 in API v3). This PR exposes it to vt-go users:

  • Error gets a new RetryAfter time.Duration field (json:"-"), set from the Retry-After response header whenever the API returns an error. It's zero when the header is absent or invalid.
  • parseRetryAfter accepts both forms allowed by RFC 9110: delta-seconds (Retry-After: 120) and an HTTP date (http.ParseTime).
  • Backwards compatible: existing fields and the Error() string are unchanged.
_, err := client.GetObject(vt.URL("files/%s", hash))
var vtErr vt.Error
if errors.As(err, &vtErr) && vtErr.Code == "QuotaExceededError" && vtErr.RetryAfter > 0 {
	time.Sleep(vtErr.RetryAfter)
}

No automatic retries are added: when a daily or monthly quota is exhausted, RetryAfter can be hours or days. Once this is released, vt-cli can use it to print a friendlier "retry in X" message.

Tests

  • TestGetObjectOutOfQuotaRetryAfter: a 429 with Retry-After: 120 yields Error{Code: "QuotaExceededError", RetryAfter: 120s}.
  • TestParseRetryAfter: empty, invalid, negative, seconds with whitespace, future HTTP date and past HTTP date.
  • The test server gained SetResponseHeader.
  • go test ./... passes. gofmt is clean for the touched files; the gofmt -l hits in feed.go, object.go and vt.go predate this change.

The VirusTotal API is starting to send a Retry-After header with
rate-limit and quota-exceeded responses. Parse it (either seconds or an
HTTP date) into the new Error.RetryAfter field so callers can wait the
right amount of time before retrying. It is zero when the header is not
present.

Co-authored-by: Oscar Torreno <torreno@google.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant