diff --git a/clients/algoliasearch-client-javascript/utils/Transporter.ts b/clients/algoliasearch-client-javascript/utils/Transporter.ts index f7fccad3ff5..e600dc6f996 100644 --- a/clients/algoliasearch-client-javascript/utils/Transporter.ts +++ b/clients/algoliasearch-client-javascript/utils/Transporter.ts @@ -22,6 +22,7 @@ import { RetryError } from './errors'; import * as responseUtils from './Response'; import { Requester } from './requester/Requester'; import { HttpRequester } from './requester/HttpRequester'; +import { stackTraceWithoutCredentials, stackFrameWithoutCredentials } from './stackTrace'; export class Transporter { private hosts: Host[]; @@ -143,7 +144,7 @@ export class Transporter { */ const host = hosts.pop(); if (host === undefined) { - throw new RetryError(stackTrace); + throw new RetryError(stackTraceWithoutCredentials(stackTrace)); } let responseTimeout = requestOptions.timeout; @@ -181,12 +182,18 @@ export class Transporter { const response = await this.requester.send(payload, request); if (responseUtils.isRetryable(response)) { - pushToStackTrace(response); + const stackFrame = pushToStackTrace(response); // If response is a timeout, we increase the number of timeouts so we can increase the timeout later. if (response.isTimedOut) { timeoutsCount++; } + /** + * Failures are individually sent to the logger, allowing + * the end user to debug / store stack frames even + * when a retry error does not happen. + */ + console.log('Retryable failure', stackFrameWithoutCredentials(stackFrame)); /** * We also store the state of the host in failure cases. If the host, is diff --git a/clients/algoliasearch-client-javascript/utils/stackTrace.ts b/clients/algoliasearch-client-javascript/utils/stackTrace.ts new file mode 100644 index 00000000000..bb4f12199fd --- /dev/null +++ b/clients/algoliasearch-client-javascript/utils/stackTrace.ts @@ -0,0 +1,22 @@ +import { StackFrame } from './types'; + +export function stackTraceWithoutCredentials(stackTrace: StackFrame[]): StackFrame[] { + return stackTrace.map((stackFrame) => stackFrameWithoutCredentials(stackFrame)); +} + +export function stackFrameWithoutCredentials(stackFrame: StackFrame): StackFrame { + const modifiedHeaders: Record = stackFrame.request.headers['x-algolia-api-key'] + ? { 'x-algolia-api-key': '*****' } + : {}; + + return { + ...stackFrame, + request: { + ...stackFrame.request, + headers: { + ...stackFrame.request.headers, + ...modifiedHeaders, + }, + }, + }; +} diff --git a/clients/utils/javascript/Transporter.ts b/clients/utils/javascript/Transporter.ts index f7fccad3ff5..0d3529d732f 100644 --- a/clients/utils/javascript/Transporter.ts +++ b/clients/utils/javascript/Transporter.ts @@ -22,6 +22,7 @@ import { RetryError } from './errors'; import * as responseUtils from './Response'; import { Requester } from './requester/Requester'; import { HttpRequester } from './requester/HttpRequester'; +import { stackTraceWithoutCredentials, stackFrameWithoutCredentials } from './stackTrace'; export class Transporter { private hosts: Host[]; @@ -143,7 +144,7 @@ export class Transporter { */ const host = hosts.pop(); if (host === undefined) { - throw new RetryError(stackTrace); + throw new RetryError(stackTraceWithoutCredentials(stackTrace)); } let responseTimeout = requestOptions.timeout; @@ -181,12 +182,18 @@ export class Transporter { const response = await this.requester.send(payload, request); if (responseUtils.isRetryable(response)) { - pushToStackTrace(response); + const stackFrame = pushToStackTrace(response); // If response is a timeout, we increase the number of timeouts so we can increase the timeout later. if (response.isTimedOut) { timeoutsCount++; } + /** + * Failures are individually send the logger, allowing + * the end user to debug / store stack frames even + * when a retry error does not happen. + */ + console.log('Retryable failure', stackFrameWithoutCredentials(stackFrame)); /** * We also store the state of the host in failure cases. If the host, is diff --git a/clients/utils/javascript/stackTrace.ts b/clients/utils/javascript/stackTrace.ts new file mode 100644 index 00000000000..bb4f12199fd --- /dev/null +++ b/clients/utils/javascript/stackTrace.ts @@ -0,0 +1,22 @@ +import { StackFrame } from './types'; + +export function stackTraceWithoutCredentials(stackTrace: StackFrame[]): StackFrame[] { + return stackTrace.map((stackFrame) => stackFrameWithoutCredentials(stackFrame)); +} + +export function stackFrameWithoutCredentials(stackFrame: StackFrame): StackFrame { + const modifiedHeaders: Record = stackFrame.request.headers['x-algolia-api-key'] + ? { 'x-algolia-api-key': '*****' } + : {}; + + return { + ...stackFrame, + request: { + ...stackFrame.request, + headers: { + ...stackFrame.request.headers, + ...modifiedHeaders, + }, + }, + }; +}