From 733e68b8879c6a9a0bed20f9f62074ab178410f7 Mon Sep 17 00:00:00 2001 From: Onur Temizkan Date: Mon, 11 Jul 2022 13:55:01 +0100 Subject: [PATCH 1/2] fix(remix): Skip capturing response errors. --- packages/remix/src/utils/instrumentServer.ts | 22 ++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/packages/remix/src/utils/instrumentServer.ts b/packages/remix/src/utils/instrumentServer.ts index 0b0dd7c18790..6a9f18d19a4d 100644 --- a/packages/remix/src/utils/instrumentServer.ts +++ b/packages/remix/src/utils/instrumentServer.ts @@ -69,7 +69,29 @@ interface DataFunction { (args: DataFunctionArgs): Promise | Response | Promise | AppData; } + +// Taken from Remix Implementation +// https://github.com/remix-run/remix/blob/7688da5c75190a2e29496c78721456d6e12e3abe/packages/remix-server-runtime/responses.ts#L54-L62 +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function isResponse(value: any): value is Response { + return ( + value != null && + /* eslint-disable @typescript-eslint/no-unsafe-member-access */ + typeof value.status === 'number' && + typeof value.statusText === 'string' && + typeof value.headers === 'object' && + typeof value.body !== 'undefined' + /* eslint-enable @typescript-eslint/no-unsafe-member-access */ + ); +} + function captureRemixServerException(err: Error, name: string): void { + // Skip capturing if the thrown error is a Response + // https://remix.run/docs/en/v1/api/conventions#throwing-responses-in-loaders + if (isResponse(err)) { + return; + } + captureException(err, scope => { scope.addEventProcessor(event => { addExceptionMechanism(event, { From 845d0ee7b5329e87677c2b478fb3afd8d6f9f404 Mon Sep 17 00:00:00 2001 From: Onur Temizkan Date: Mon, 11 Jul 2022 18:10:44 +0100 Subject: [PATCH 2/2] Capture only erroneous responses. --- packages/remix/src/utils/instrumentServer.ts | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/packages/remix/src/utils/instrumentServer.ts b/packages/remix/src/utils/instrumentServer.ts index 6a9f18d19a4d..a39b12f7e46e 100644 --- a/packages/remix/src/utils/instrumentServer.ts +++ b/packages/remix/src/utils/instrumentServer.ts @@ -69,7 +69,6 @@ interface DataFunction { (args: DataFunctionArgs): Promise | Response | Promise | AppData; } - // Taken from Remix Implementation // https://github.com/remix-run/remix/blob/7688da5c75190a2e29496c78721456d6e12e3abe/packages/remix-server-runtime/responses.ts#L54-L62 // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -85,14 +84,26 @@ function isResponse(value: any): value is Response { ); } +// Taken from Remix Implementation +// https://github.com/remix-run/remix/blob/7688da5c75190a2e29496c78721456d6e12e3abe/packages/remix-server-runtime/data.ts#L131-L145 +function extractData(response: Response): Promise { + const contentType = response.headers.get('Content-Type'); + + if (contentType && /\bapplication\/json\b/.test(contentType)) { + return response.json(); + } + + return response.text(); +} + function captureRemixServerException(err: Error, name: string): void { - // Skip capturing if the thrown error is a Response + // Skip capturing if the thrown error is an OK Response // https://remix.run/docs/en/v1/api/conventions#throwing-responses-in-loaders - if (isResponse(err)) { + if (isResponse(err) && err.status < 400) { return; } - captureException(err, scope => { + captureException(isResponse(err) ? extractData(err) : err, scope => { scope.addEventProcessor(event => { addExceptionMechanism(event, { type: 'instrument',