From f76f9d73a0f4ea75ff854d4d1352138dfcbcb23a Mon Sep 17 00:00:00 2001 From: Billy Vong Date: Mon, 6 Mar 2023 12:00:18 -0500 Subject: [PATCH 1/2] feat(replay): Attach an error `cause` to send exceptions Attach the original exception as a `cause` when we throw "Unable to send replay" exceptions so that we know what is causing issues with sending replays. --- packages/replay/src/util/sendReplay.ts | 12 +++++++++++- packages/replay/src/util/sendReplayRequest.ts | 13 +++++++++++-- .../replay/test/integration/sendReplayEvent.test.ts | 3 +++ 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/packages/replay/src/util/sendReplay.ts b/packages/replay/src/util/sendReplay.ts index e393c8611866..f10bb223d3d9 100644 --- a/packages/replay/src/util/sendReplay.ts +++ b/packages/replay/src/util/sendReplay.ts @@ -41,7 +41,17 @@ export async function sendReplay( // If an error happened here, it's likely that uploading the attachment // failed, we'll can retry with the same events payload if (retryConfig.count >= RETRY_MAX_COUNT) { - throw new Error(`${UNABLE_TO_SEND_REPLAY} - max retries exceeded`); + const error = new Error(`${UNABLE_TO_SEND_REPLAY} - max retries exceeded`); + + try { + // In case browsers don't allow this property to be writable + // @ts-ignore This needs lib es2022 and newer + error.cause = err; + } catch { + // nothing to do + } + + throw error; } // will retry in intervals of 5, 10, 30 diff --git a/packages/replay/src/util/sendReplayRequest.ts b/packages/replay/src/util/sendReplayRequest.ts index 06e35330937e..2d512915ba47 100644 --- a/packages/replay/src/util/sendReplayRequest.ts +++ b/packages/replay/src/util/sendReplayRequest.ts @@ -115,8 +115,17 @@ export async function sendReplayRequest({ try { response = await transport.send(envelope); - } catch { - throw new Error(UNABLE_TO_SEND_REPLAY); + } catch (err) { + const error = new Error(UNABLE_TO_SEND_REPLAY); + + try { + // In case browsers don't allow this property to be writable + // @ts-ignore This needs lib es2022 and newer + error.cause = err; + } catch { + // nothing to do + } + throw error; } // TODO (v8): we can remove this guard once transport.send's type signature doesn't include void anymore diff --git a/packages/replay/test/integration/sendReplayEvent.test.ts b/packages/replay/test/integration/sendReplayEvent.test.ts index 4f17644a241e..f2510d201cbf 100644 --- a/packages/replay/test/integration/sendReplayEvent.test.ts +++ b/packages/replay/test/integration/sendReplayEvent.test.ts @@ -371,6 +371,9 @@ describe('Integration | sendReplayEvent', () => { expect(spyHandleException).toHaveBeenCalledTimes(5); expect(spyHandleException).toHaveBeenLastCalledWith(new Error('Unable to send Replay - max retries exceeded')); + const spyHandleExceptionCall = spyHandleException.mock.calls + expect(spyHandleExceptionCall[spyHandleExceptionCall.length-1][0].cause.message).toEqual('Something bad happened'); + // No activity has occurred, session's last activity should remain the same expect(replay.session?.lastActivity).toBe(BASE_TIMESTAMP); From 77d156e44ff5a30803c90ce90080b9113a61b3ef Mon Sep 17 00:00:00 2001 From: Billy Vong Date: Mon, 6 Mar 2023 17:11:48 -0500 Subject: [PATCH 2/2] lint --- packages/replay/test/integration/sendReplayEvent.test.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/replay/test/integration/sendReplayEvent.test.ts b/packages/replay/test/integration/sendReplayEvent.test.ts index f2510d201cbf..f38b4ae0e256 100644 --- a/packages/replay/test/integration/sendReplayEvent.test.ts +++ b/packages/replay/test/integration/sendReplayEvent.test.ts @@ -371,8 +371,10 @@ describe('Integration | sendReplayEvent', () => { expect(spyHandleException).toHaveBeenCalledTimes(5); expect(spyHandleException).toHaveBeenLastCalledWith(new Error('Unable to send Replay - max retries exceeded')); - const spyHandleExceptionCall = spyHandleException.mock.calls - expect(spyHandleExceptionCall[spyHandleExceptionCall.length-1][0].cause.message).toEqual('Something bad happened'); + const spyHandleExceptionCall = spyHandleException.mock.calls; + expect(spyHandleExceptionCall[spyHandleExceptionCall.length - 1][0].cause.message).toEqual( + 'Something bad happened', + ); // No activity has occurred, session's last activity should remain the same expect(replay.session?.lastActivity).toBe(BASE_TIMESTAMP);