Refactor error handling in isRateLimitError function for improved clarity

This commit is contained in:
priyagupta108 2026-07-09 09:40:20 +05:30
parent 9737be46d4
commit 0bc3767d34
3 changed files with 8 additions and 12 deletions

View file

@ -57,7 +57,6 @@ describe('getManifest', () => {
it('should fall back to URL if repo returns a truncated/empty manifest', async () => { it('should fall back to URL if repo returns a truncated/empty manifest', async () => {
jest.useFakeTimers(); jest.useFakeTimers();
// Simulate a truncated response that parses to an empty array.
(tc.getManifestFromRepo as jest.Mock).mockResolvedValue([]); (tc.getManifestFromRepo as jest.Mock).mockResolvedValue([]);
(httpm.HttpClient.prototype.getJson as jest.Mock).mockResolvedValue({ (httpm.HttpClient.prototype.getJson as jest.Mock).mockResolvedValue({
result: mockManifest result: mockManifest
@ -71,9 +70,7 @@ describe('getManifest', () => {
it('should retry on a transient invalid manifest and then succeed', async () => { it('should retry on a transient invalid manifest and then succeed', async () => {
jest.useFakeTimers(); jest.useFakeTimers();
(tc.getManifestFromRepo as jest.Mock) (tc.getManifestFromRepo as jest.Mock)
// First attempt returns a truncated/empty body.
.mockResolvedValueOnce([]) .mockResolvedValueOnce([])
// Retry returns a valid manifest.
.mockResolvedValueOnce(mockManifest); .mockResolvedValueOnce(mockManifest);
const promise = getManifest(); const promise = getManifest();
await jest.runAllTimersAsync(); await jest.runAllTimersAsync();
@ -84,13 +81,12 @@ describe('getManifest', () => {
it('should fail loudly when the manifest is truncated/empty on every source', async () => { it('should fail loudly when the manifest is truncated/empty on every source', async () => {
jest.useFakeTimers(); jest.useFakeTimers();
// Both the API and the raw URL keep returning truncated/empty bodies.
(tc.getManifestFromRepo as jest.Mock).mockResolvedValue([]); (tc.getManifestFromRepo as jest.Mock).mockResolvedValue([]);
(httpm.HttpClient.prototype.getJson as jest.Mock).mockResolvedValue({ (httpm.HttpClient.prototype.getJson as jest.Mock).mockResolvedValue({
result: [] result: []
}); });
const promise = getManifest(); const promise = getManifest();
// Attach a rejection handler before advancing timers to avoid unhandled rejection warnings. // Prevent unhandled rejection before timers advance.
const catchPromise = promise.catch(() => {}); const catchPromise = promise.catch(() => {});
await jest.runAllTimersAsync(); await jest.runAllTimersAsync();
await catchPromise; await catchPromise;
@ -107,8 +103,6 @@ describe('getManifest', () => {
(httpm.HttpClient.prototype.getJson as jest.Mock).mockResolvedValue({ (httpm.HttpClient.prototype.getJson as jest.Mock).mockResolvedValue({
result: mockManifest result: mockManifest
}); });
// No fake timers needed: a rate-limit error must short-circuit retries
// (and their backoff) and fall straight through to the URL fallback.
const manifest = await getManifest(); const manifest = await getManifest();
expect(manifest).toEqual(mockManifest); expect(manifest).toEqual(mockManifest);
expect(tc.getManifestFromRepo as jest.Mock).toHaveBeenCalledTimes(1); expect(tc.getManifestFromRepo as jest.Mock).toHaveBeenCalledTimes(1);

4
dist/setup/index.js vendored
View file

@ -55725,8 +55725,8 @@ function sleep(ms) {
} }
// HTTP 403/429 from http-client (`statusCode`) or tool-cache (`httpStatusCode`). // HTTP 403/429 from http-client (`statusCode`) or tool-cache (`httpStatusCode`).
function isRateLimitError(err) { function isRateLimitError(err) {
const status = err.httpStatusCode ?? const e = err;
err.statusCode; const status = e?.httpStatusCode ?? e?.statusCode;
return status === 403 || status === 429; return status === 403 || status === 429;
} }
// Fetches and validates a manifest, retrying transient failures with backoff. // Fetches and validates a manifest, retrying transient failures with backoff.

View file

@ -151,9 +151,11 @@ function sleep(ms: number): Promise<void> {
// HTTP 403/429 from http-client (`statusCode`) or tool-cache (`httpStatusCode`). // HTTP 403/429 from http-client (`statusCode`) or tool-cache (`httpStatusCode`).
function isRateLimitError(err: unknown): boolean { function isRateLimitError(err: unknown): boolean {
const status = const e = err as
(err as {httpStatusCode?: number}).httpStatusCode ?? | {httpStatusCode?: number; statusCode?: number}
(err as {statusCode?: number}).statusCode; | null
| undefined;
const status = e?.httpStatusCode ?? e?.statusCode;
return status === 403 || status === 429; return status === 403 || status === 429;
} }