From 1e1e6fc5e9a10828ad196173f770ae51cc83757f Mon Sep 17 00:00:00 2001 From: amandeepsingh333 Date: Thu, 19 Sep 2024 13:42:04 +0530 Subject: [PATCH] Throttle Logs Endpoint from CLI --- packages/core/src/percy.js | 11 ++++++++++ packages/core/test/percy.test.js | 36 ++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/packages/core/src/percy.js b/packages/core/src/percy.js index 333801783..59c552873 100644 --- a/packages/core/src/percy.js +++ b/packages/core/src/percy.js @@ -29,6 +29,8 @@ import { } from './discovery.js'; import { WaitForJob } from './wait-for-job.js'; +const MAX_SUGGESTION_CALLS = 10; + // A Percy instance will create a new build when started, handle snapshot creation, asset discovery, // and resource uploads, and will finalize the build when stopped. Snapshots are processed // concurrently and the build is not finalized until all snapshots have been handled. @@ -72,6 +74,7 @@ export class Percy { server = true, port = 5338, projectType = null, + suggestionsCallCounter = 0, // options such as `snapshot` and `discovery` that are valid Percy config // options which will become accessible via the `.config` property ...options @@ -98,6 +101,7 @@ export class Percy { this.delayUploads = this.skipUploads || !!delayUploads; this.deferUploads = this.skipUploads || !!deferUploads; this.labels = labels; + this.suggestionsCallCounter = suggestionsCallCounter; this.client = new PercyClient({ token, clientInfo, environmentInfo, config, labels }); if (server) this.server = createPercyServer(this, port); @@ -507,6 +511,13 @@ export class Percy { async suggestionsForFix(errors, options = {}) { try { + this.suggestionsCallCounter++; + if (this.suggestionsCallCounter > MAX_SUGGESTION_CALLS) { + if (this.suggestionsCallCounter === MAX_SUGGESTION_CALLS + 1) { + this.log.debug('Rate limit exceeded for Maximum allowed suggestions per build.'); + } + return; + } const suggestionResponse = await this.client.getErrorAnalysis(errors); this.#displaySuggestionLogs(suggestionResponse, options); } catch (e) { diff --git a/packages/core/test/percy.test.js b/packages/core/test/percy.test.js index 4228e73c1..6ef1595f6 100644 --- a/packages/core/test/percy.test.js +++ b/packages/core/test/percy.test.js @@ -1301,6 +1301,42 @@ describe('Percy', () => { }); }); + describe('check for throttle logs endpoint from CLI', () => { + let maxSuggestionCalls = 10; + it('should increment suggestionsCallCounter and not call getErrorAnalysis after exceeding the rate limit', async () => { + spyOn(percy.client, 'getErrorAnalysis').and.returnValue([{ + suggestion: 'some suggestion', + failure_reason: 'some failure reason' + }]); + percy.loglevel('debug'); + + for (let i = 0; i <= maxSuggestionCalls; i++) { + await expectAsync(percy.suggestionsForFix('some_error')).toBeResolved(); + } + + await expectAsync(percy.suggestionsForFix('some_error')).toBeResolved(); + + expect(percy.client.getErrorAnalysis.calls.count()).toBe(maxSuggestionCalls); + expect(logger.stderr).toEqual(jasmine.arrayContaining([ + '[percy:core] Rate limit exceeded for Maximum allowed suggestions per build.' + ])); + }); + + it('should printed debug log for rate limiting only once, even after it exceeded multiple times', async () => { + spyOn(percy.log, 'debug').and.callThrough(); + percy.loglevel('debug'); + + for (let i = 0; i <= maxSuggestionCalls + 5; i++) { + await expectAsync(percy.suggestionsForFix('some_error')).toBeResolved(); + } + + expect(percy.log.debug).toHaveBeenCalledWith( + 'Rate limit exceeded for Maximum allowed suggestions per build.' + ); + expect(percy.log.debug.calls.count()).toBe(1); + }); + }); + describe('when response throw error', () => { describe('when Request failed with error code of EHOSTUNREACH', () => { it('should catch and logs expected error', async () => {