From 5b951c650d329ea62e307c7207f38716db3b30c3 Mon Sep 17 00:00:00 2001 From: Billy Vong Date: Fri, 26 Jul 2024 14:30:20 -0400 Subject: [PATCH 1/3] feat(replay): Capture exception when `internal_sdk_error` client report happens We currently have no visibility when this client report happens. Lets capture the exception if our experimental flag is on. Also refactors `_handleException()` to be a public method instead of private. --- packages/replay-internal/src/replay.ts | 32 +++++++++---------- packages/replay-internal/src/util/addEvent.ts | 2 ++ 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/packages/replay-internal/src/replay.ts b/packages/replay-internal/src/replay.ts index a0ef13276e1a..f42d6ef6964a 100644 --- a/packages/replay-internal/src/replay.ts +++ b/packages/replay-internal/src/replay.ts @@ -241,6 +241,15 @@ export class ReplayContainer implements ReplayContainerInterface { return this._options; } + /** A wrapper to conditionally capture exceptions. */ + public handleException(error: unknown): void { + DEBUG_BUILD && logger.error('[Replay]', error); + + if (DEBUG_BUILD && this._options._experiments && this._options._experiments.captureExceptions) { + captureException(error); + } + } + /** * Initializes the plugin based on sampling configuration. Should not be * called outside of constructor. @@ -264,7 +273,7 @@ export class ReplayContainer implements ReplayContainerInterface { if (!this.session) { // This should not happen, something wrong has occurred - this._handleException(new Error('Unable to initialize and create session')); + this.handleException(new Error('Unable to initialize and create session')); return; } @@ -389,7 +398,7 @@ export class ReplayContainer implements ReplayContainerInterface { : {}), }); } catch (err) { - this._handleException(err); + this.handleException(err); } } @@ -408,7 +417,7 @@ export class ReplayContainer implements ReplayContainerInterface { return true; } catch (err) { - this._handleException(err); + this.handleException(err); return false; } } @@ -450,7 +459,7 @@ export class ReplayContainer implements ReplayContainerInterface { // is started after, it will not have `previousSessionId` clearSession(this); } catch (err) { - this._handleException(err); + this.handleException(err); } } @@ -777,15 +786,6 @@ export class ReplayContainer implements ReplayContainerInterface { this.startRecording(); } - /** A wrapper to conditionally capture exceptions. */ - private _handleException(error: unknown): void { - DEBUG_BUILD && logger.error('[Replay]', error); - - if (DEBUG_BUILD && this._options._experiments && this._options._experiments.captureExceptions) { - captureException(error); - } - } - /** * Loads (or refreshes) the current session. */ @@ -873,7 +873,7 @@ export class ReplayContainer implements ReplayContainerInterface { this._hasInitializedCoreListeners = true; } } catch (err) { - this._handleException(err); + this.handleException(err); } this._performanceCleanupCallback = setupPerformanceObserver(this); @@ -898,7 +898,7 @@ export class ReplayContainer implements ReplayContainerInterface { this._performanceCleanupCallback(); } } catch (err) { - this._handleException(err); + this.handleException(err); } } @@ -1161,7 +1161,7 @@ export class ReplayContainer implements ReplayContainerInterface { timestamp, }); } catch (err) { - this._handleException(err); + this.handleException(err); // This means we retried 3 times and all of them failed, // or we ran into a problem we don't want to retry, like rate limiting. diff --git a/packages/replay-internal/src/util/addEvent.ts b/packages/replay-internal/src/util/addEvent.ts index b2a011687428..891694682756 100644 --- a/packages/replay-internal/src/util/addEvent.ts +++ b/packages/replay-internal/src/util/addEvent.ts @@ -83,6 +83,8 @@ async function _addEvent( DEBUG_BUILD && logger.error(error); await replay.stop({ reason }); + replay.handleException(error); + const client = getClient(); if (client) { From 4fb32658b2137865912527037afa99704af74c17 Mon Sep 17 00:00:00 2001 From: Billy Vong Date: Fri, 26 Jul 2024 14:34:05 -0400 Subject: [PATCH 2/3] types --- packages/replay-internal/src/types/replay.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/replay-internal/src/types/replay.ts b/packages/replay-internal/src/types/replay.ts index 7ebacad9e100..1e510e2bc519 100644 --- a/packages/replay-internal/src/types/replay.ts +++ b/packages/replay-internal/src/types/replay.ts @@ -485,6 +485,7 @@ export interface ReplayContainer { checkAndHandleExpiredSession(): boolean | void; setInitialState(): void; getCurrentRoute(): string | undefined; + handleException(err: unknown): void; } type RequestBody = null | Blob | BufferSource | FormData | URLSearchParams | string; From 370194f3e30f33659c883a57896d81302a6d4355 Mon Sep 17 00:00:00 2001 From: Billy Vong Date: Mon, 29 Jul 2024 15:50:11 -0400 Subject: [PATCH 3/3] remove logger.error --- packages/replay-internal/src/util/addEvent.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/replay-internal/src/util/addEvent.ts b/packages/replay-internal/src/util/addEvent.ts index 891694682756..f397ea0564f6 100644 --- a/packages/replay-internal/src/util/addEvent.ts +++ b/packages/replay-internal/src/util/addEvent.ts @@ -79,12 +79,10 @@ async function _addEvent( return await replay.eventBuffer.addEvent(eventAfterPossibleCallback); } catch (error) { const reason = error && error instanceof EventBufferSizeExceededError ? 'addEventSizeExceeded' : 'addEvent'; + replay.handleException(error); - DEBUG_BUILD && logger.error(error); await replay.stop({ reason }); - replay.handleException(error); - const client = getClient(); if (client) {