diff --git a/src/Rokt-Kit.ts b/src/Rokt-Kit.ts index 5f91127..470774d 100644 --- a/src/Rokt-Kit.ts +++ b/src/Rokt-Kit.ts @@ -647,22 +647,12 @@ class LoggingService { log(entry: LogEntry | null | undefined): void { if (!entry) return; - this._transport.send( - this._loggingUrl, - WSDKErrorSeverity.INFO, - entry.message, - entry.code, - undefined, - (error: Error) => { - if (this._errorReportingService) { - this._errorReportingService.report({ - message: 'LoggingService: Failed to send log: ' + error.message, - code: ErrorCodes.UNKNOWN_ERROR, - severity: WSDKErrorSeverity.ERROR, - }); - } - }, - ); + // Fire-and-forget: a failed diagnostics-log send must NOT be re-reported as an + // error beacon. Doing so creates a feedback loop — when /v1/log is rate-limited, + // the 429 surfaces to fetch as "Failed to fetch", and reporting it would emit a + // /v1/errors beacon that is itself rate-limited, amplifying load at the log + // frequency. ReportingTransport already logs the failure to the console. + this._transport.send(this._loggingUrl, WSDKErrorSeverity.INFO, entry.message, entry.code); } } diff --git a/test/src/tests.spec.ts b/test/src/tests.spec.ts index 8fc54b8..1ba7785 100644 --- a/test/src/tests.spec.ts +++ b/test/src/tests.spec.ts @@ -6338,14 +6338,14 @@ describe('Rokt Forwarder', () => { expect(body.additionalInformation.message).toBe('log entry'); }); - it('should report failure through ErrorReportingService on fetch error', async () => { + it('should NOT report failure as an error beacon on fetch error (fire-and-forget, no feedback loop)', async () => { const errorReports: any[] = []; const errorService = { report: (error: any) => { errorReports.push(error); }, }; - (window as any).fetch = () => Promise.reject(new Error('Network failure')); + (window as any).fetch = () => Promise.reject(new Error('Failed to fetch')); const originalConsoleError = console.error; console.error = () => {}; @@ -6353,9 +6353,9 @@ describe('Rokt Forwarder', () => { service.log({ message: 'test' }); await new Promise((resolve) => setTimeout(resolve, 50)); - expect(errorReports.length).toBeGreaterThan(0); - expect(errorReports[0].severity).toBe('ERROR'); - expect(errorReports[0].message).toContain('Failed to send log'); + // A failed /v1/log send must not generate a /v1/errors beacon — otherwise a + // rate-limited log send amplifies into rate-limited error traffic. + expect(errorReports.length).toBe(0); console.error = originalConsoleError; });