From 879cfe327788e2e3c4a140840371868cfa62bcbc Mon Sep 17 00:00:00 2001 From: Tim Yiu <137842098+tyiuhc@users.noreply.github.com> Date: Wed, 30 Oct 2024 10:44:25 -0700 Subject: [PATCH] fix: catch variant/flag fetch timeout error and log at debug-level (#135) --- .../src/experimentClient.ts | 30 ++++++++++++++----- .../experiment-browser/src/transport/http.ts | 9 ++++-- .../experiment-core/src/evaluation/error.ts | 7 +++++ packages/experiment-core/src/index.ts | 2 +- 4 files changed, 37 insertions(+), 11 deletions(-) diff --git a/packages/experiment-browser/src/experimentClient.ts b/packages/experiment-browser/src/experimentClient.ts index e4fd5bc4..0aabab8f 100644 --- a/packages/experiment-browser/src/experimentClient.ts +++ b/packages/experiment-browser/src/experimentClient.ts @@ -12,6 +12,7 @@ import { Poller, SdkEvaluationApi, SdkFlagApi, + TimeoutError, topologicalSort, } from '@amplitude/experiment-core'; @@ -255,7 +256,11 @@ export class ExperimentClient implements Client { ); } catch (e) { if (this.config.debug) { - console.error(e); + if (e instanceof TimeoutError) { + console.debug(e); + } else { + console.error(e); + } } } return this; @@ -697,13 +702,22 @@ export class ExperimentClient implements Client { } private async doFlags(): Promise { - const flags = await this.flagApi.getFlags({ - libraryName: 'experiment-js-client', - libraryVersion: PACKAGE_VERSION, - timeoutMillis: this.config.fetchTimeoutMillis, - }); - this.flags.clear(); - this.flags.putAll(flags); + try { + const flags = await this.flagApi.getFlags({ + libraryName: 'experiment-js-client', + libraryVersion: PACKAGE_VERSION, + timeoutMillis: this.config.fetchTimeoutMillis, + }); + this.flags.clear(); + this.flags.putAll(flags); + } catch (e) { + if (this.config.debug && e instanceof TimeoutError) { + console.debug(e); + } else { + throw e; + } + } + try { this.flags.store(); } catch (e) { diff --git a/packages/experiment-browser/src/transport/http.ts b/packages/experiment-browser/src/transport/http.ts index b0b6f9e4..b87c3750 100644 --- a/packages/experiment-browser/src/transport/http.ts +++ b/packages/experiment-browser/src/transport/http.ts @@ -3,7 +3,7 @@ * @internal */ -import { safeGlobal } from '@amplitude/experiment-core'; +import { safeGlobal, TimeoutError } from '@amplitude/experiment-core'; import { HttpClient as CoreHttpClient, HttpRequest, @@ -29,7 +29,11 @@ const timeout = ( } return new Promise(function (resolve, reject) { safeGlobal.setTimeout(function () { - reject(Error('Request timeout after ' + timeoutMillis + ' milliseconds')); + reject( + new TimeoutError( + 'Request timeout after ' + timeoutMillis + ' milliseconds', + ), + ); }, timeoutMillis); promise.then(resolve, reject); }); @@ -63,6 +67,7 @@ const _request = ( */ export class WrapperClient implements CoreHttpClient { private readonly client: HttpClient; + constructor(client: HttpClient) { this.client = client; } diff --git a/packages/experiment-core/src/evaluation/error.ts b/packages/experiment-core/src/evaluation/error.ts index b24e516d..c03b8a75 100644 --- a/packages/experiment-core/src/evaluation/error.ts +++ b/packages/experiment-core/src/evaluation/error.ts @@ -7,3 +7,10 @@ export class FetchError extends Error { Object.setPrototypeOf(this, FetchError.prototype); } } + +export class TimeoutError extends Error { + constructor(message: string) { + super(message); + Object.setPrototypeOf(this, TimeoutError.prototype); + } +} diff --git a/packages/experiment-core/src/index.ts b/packages/experiment-core/src/index.ts index 09bd0b37..d5f1bb83 100644 --- a/packages/experiment-core/src/index.ts +++ b/packages/experiment-core/src/index.ts @@ -23,4 +23,4 @@ export { getGlobalScope, isLocalStorageAvailable, } from './util/global'; -export { FetchError } from './evaluation/error'; +export { FetchError, TimeoutError } from './evaluation/error';