From dcc15b15a7d6f089b837515165cc7d5b0d456d4e Mon Sep 17 00:00:00 2001 From: Charly Gomez Date: Mon, 13 Jan 2025 13:16:00 +0100 Subject: [PATCH 01/16] bump deps --- packages/remix/package.json | 10 +-- yarn.lock | 149 ++++++++++++++++++------------------ 2 files changed, 80 insertions(+), 79 deletions(-) diff --git a/packages/remix/package.json b/packages/remix/package.json index 3b71804e5da7..6706937895c7 100644 --- a/packages/remix/package.json +++ b/packages/remix/package.json @@ -64,16 +64,16 @@ "yargs": "^17.6.0" }, "devDependencies": { - "@remix-run/node": "^1.4.3", - "@remix-run/react": "^1.4.3", + "@remix-run/node": "^2.15.2", + "@remix-run/react": "^2.15.2", "@types/express": "^4.17.14", "vite": "^5.4.10", "vitest": "^1.6.0" }, "peerDependencies": { - "@remix-run/node": "1.x || 2.x", - "@remix-run/react": "1.x || 2.x", - "react": "16.x || 17.x || 18.x" + "@remix-run/node": "2.x", + "@remix-run/react": "2.x", + "react": "18.x" }, "scripts": { "build": "run-p build:transpile build:types", diff --git a/yarn.lock b/yarn.lock index d8ec4c17d850..62a9fd5dbcd9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4145,7 +4145,7 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.1.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.0", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4": +"@babel/runtime@^7.1.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.0", "@babel/runtime@^7.8.4": version "7.19.4" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.19.4.tgz#a42f814502ee467d55b38dd1c256f53a7b885c78" integrity sha512-EXpLCrk55f+cYqmHsSR+yD/0gAIMxxA9QK9lnQWzhMCvt+YmoBN7Zx94s++Kv0+unHk39vxNO8t+CMA2WSS3wA== @@ -8230,28 +8230,29 @@ resolved "https://registry.yarnpkg.com/@redis/time-series/-/time-series-1.0.5.tgz#a6d70ef7a0e71e083ea09b967df0a0ed742bc6ad" integrity sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg== -"@remix-run/node@^1.4.3": - version "1.5.1" - resolved "https://registry.yarnpkg.com/@remix-run/node/-/node-1.5.1.tgz#1c367d4035baaef8f0ea66962a826456d62f0030" - integrity sha512-yl4bd1nl7MiJp4tI3+4ygObeMU3txM4Uo09IdHLRa4NMdBQnacUJ47kqCahny01MerC2JL2d9NPjdVPwRCRZvQ== +"@remix-run/node@^2.15.2": + version "2.15.2" + resolved "https://registry.yarnpkg.com/@remix-run/node/-/node-2.15.2.tgz#7ea460335b66a06d22e554a84edf09e2b8879a8a" + integrity sha512-NS/h5uxje7DYCNgcKqKAiUhf0r2HVnoYUBWLyIIMmCUP1ddWurBP6xTPcWzGhEvV/EvguniYi1wJZ5+X8sonWw== dependencies: - "@remix-run/server-runtime" "1.5.1" - "@remix-run/web-fetch" "^4.1.3" - "@remix-run/web-file" "^3.0.2" - "@remix-run/web-stream" "^1.0.3" + "@remix-run/server-runtime" "2.15.2" + "@remix-run/web-fetch" "^4.4.2" "@web3-storage/multipart-parser" "^1.0.0" - abort-controller "^3.0.0" cookie-signature "^1.1.0" source-map-support "^0.5.21" stream-slice "^0.1.2" + undici "^6.11.1" -"@remix-run/react@^1.4.3": - version "1.5.1" - resolved "https://registry.yarnpkg.com/@remix-run/react/-/react-1.5.1.tgz#372e5e80f3f10a638b0567c4e03307dfb0a28dc0" - integrity sha512-p4t6tC/WyPeLW7DO4g7ZSyH9EpWO37c4wD2np3rDwtv3WtsTZ70bU/+NOWE9nv74mH8i1C50eJ3/OR+8Ll8UbA== +"@remix-run/react@^2.15.2": + version "2.15.2" + resolved "https://registry.yarnpkg.com/@remix-run/react/-/react-2.15.2.tgz#4f57434c120e0b7885d8b737c417b67f72a3a042" + integrity sha512-NAAMsSgoC/sdOgovUewwRCE/RUm3F+MBxxZKfwu3POCNeHaplY5qGkH/y8PUXvdN1EBG7Z0Ko43dyzCfcEy5PA== dependencies: - history "^5.3.0" - react-router-dom "^6.2.2" + "@remix-run/router" "1.21.0" + "@remix-run/server-runtime" "2.15.2" + react-router "6.28.1" + react-router-dom "6.28.1" + turbo-stream "2.4.0" "@remix-run/router@1.21.0": version "1.21.0" @@ -8263,57 +8264,59 @@ resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.15.0.tgz#461a952c2872dd82c8b2e9b74c4dfaff569123e2" integrity sha512-HOil5aFtme37dVQTB6M34G95kPM3MMuqSmIRVCC52eKV+Y/tGSqw9P3rWhlAx6A+mz+MoX+XxsGsNJbaI5qCgQ== -"@remix-run/server-runtime@1.5.1": - version "1.5.1" - resolved "https://registry.yarnpkg.com/@remix-run/server-runtime/-/server-runtime-1.5.1.tgz#5272b01e6dce109dc10bd68447ceae2d039315b2" - integrity sha512-FQbCCdW+qzE3wpoCwUKdwcL8yZVYNPiyHS9JS/6r6qmd/yvZfbj44E48wEQ6trbWE2TUiEh/EQqNMyrZWEs4bw== +"@remix-run/server-runtime@2.15.2": + version "2.15.2" + resolved "https://registry.yarnpkg.com/@remix-run/server-runtime/-/server-runtime-2.15.2.tgz#5be945027612c0891748d1788d39fea1ef0ba33c" + integrity sha512-OqiPcvEnnU88B8b1LIWHHkQ3Tz2GDAmQ1RihFNQsbrFKpDsQLkw0lJlnfgKA/uHd0CEEacpfV7C9qqJT3V6Z2g== dependencies: - "@types/cookie" "^0.4.0" + "@remix-run/router" "1.21.0" + "@types/cookie" "^0.6.0" "@web3-storage/multipart-parser" "^1.0.0" - cookie "^0.4.1" - jsesc "^3.0.1" - react-router-dom "^6.2.2" + cookie "^0.6.0" set-cookie-parser "^2.4.8" source-map "^0.7.3" + turbo-stream "2.4.0" -"@remix-run/web-blob@^3.0.3", "@remix-run/web-blob@^3.0.4": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@remix-run/web-blob/-/web-blob-3.0.4.tgz#99c67b9d0fb641bd0c07d267fd218ae5aa4ae5ed" - integrity sha512-AfegzZvSSDc+LwnXV+SwROTrDtoLiPxeFW+jxgvtDAnkuCX1rrzmVJ6CzqZ1Ai0bVfmJadkG5GxtAfYclpPmgw== +"@remix-run/web-blob@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@remix-run/web-blob/-/web-blob-3.1.0.tgz#e0c669934c1eb6028960047e57a13ed38bbfb434" + integrity sha512-owGzFLbqPH9PlKb8KvpNJ0NO74HWE2euAn61eEiyCXX/oteoVzTVSN8mpLgDjaxBf2btj5/nUllSUgpyd6IH6g== dependencies: - "@remix-run/web-stream" "^1.0.0" + "@remix-run/web-stream" "^1.1.0" web-encoding "1.1.5" -"@remix-run/web-fetch@^4.1.3": - version "4.1.3" - resolved "https://registry.yarnpkg.com/@remix-run/web-fetch/-/web-fetch-4.1.3.tgz#8ad3077c1b5bd9fe2a8813d0ad3c84970a495c04" - integrity sha512-D3KXAEkzhR248mu7wCHReQrMrIo3Y9pDDa7TrlISnsOEvqkfWkJJF+PQWmOIKpOSHAhDg7TCb2tzvW8lc/MfHw== +"@remix-run/web-fetch@^4.4.2": + version "4.4.2" + resolved "https://registry.yarnpkg.com/@remix-run/web-fetch/-/web-fetch-4.4.2.tgz#ce7aedef72cc26e15060e8cf84674029f92809b6" + integrity sha512-jgKfzA713/4kAW/oZ4bC3MoLWyjModOVDjFPNseVqcJKSafgIscrYL9G50SurEYLswPuoU3HzSbO0jQCMYWHhA== dependencies: - "@remix-run/web-blob" "^3.0.4" - "@remix-run/web-form-data" "^3.0.2" - "@remix-run/web-stream" "^1.0.3" + "@remix-run/web-blob" "^3.1.0" + "@remix-run/web-file" "^3.1.0" + "@remix-run/web-form-data" "^3.1.0" + "@remix-run/web-stream" "^1.1.0" "@web3-storage/multipart-parser" "^1.0.0" + abort-controller "^3.0.0" data-uri-to-buffer "^3.0.1" mrmime "^1.0.0" -"@remix-run/web-file@^3.0.2": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@remix-run/web-file/-/web-file-3.0.2.tgz#1a6cc0900a1310ede4bc96abad77ac6eb27a2131" - integrity sha512-eFC93Onh/rZ5kUNpCQersmBtxedGpaXK2/gsUl49BYSGK/DvuPu3l06vmquEDdcPaEuXcsdGP0L7zrmUqrqo4A== +"@remix-run/web-file@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@remix-run/web-file/-/web-file-3.1.0.tgz#07219021a2910e90231bc30ca1ce693d0e9d3825" + integrity sha512-dW2MNGwoiEYhlspOAXFBasmLeYshyAyhIdrlXBi06Duex5tDr3ut2LFKVj7tyHLmn8nnNwFf1BjNbkQpygC2aQ== dependencies: - "@remix-run/web-blob" "^3.0.3" + "@remix-run/web-blob" "^3.1.0" -"@remix-run/web-form-data@^3.0.2": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@remix-run/web-form-data/-/web-form-data-3.0.2.tgz#733a4c8f8176523b7b60a8bd0dc6704fd4d498f3" - integrity sha512-F8tm3iB1sPxMpysK6Js7lV3gvLfTNKGmIW38t/e6dtPEB5L1WdbRG1cmLyhsonFc7rT1x1JKdz+2jCtoSdnIUw== +"@remix-run/web-form-data@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@remix-run/web-form-data/-/web-form-data-3.1.0.tgz#47f9ad8ce8bf1c39ed83eab31e53967fe8e3df6a" + integrity sha512-NdeohLMdrb+pHxMQ/Geuzdp0eqPbea+Ieo8M8Jx2lGC6TBHsgHzYcBvr0LyPdPVycNRDEpWpiDdCOdCryo3f9A== dependencies: web-encoding "1.1.5" -"@remix-run/web-stream@^1.0.0", "@remix-run/web-stream@^1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@remix-run/web-stream/-/web-stream-1.0.3.tgz#3284a6a45675d1455c4d9c8f31b89225c9006438" - integrity sha512-wlezlJaA5NF6SsNMiwQnnAW6tnPzQ5I8qk0Y0pSohm0eHKa2FQ1QhEKLVVcDDu02TmkfHgnux0igNfeYhDOXiA== +"@remix-run/web-stream@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@remix-run/web-stream/-/web-stream-1.1.0.tgz#b93a8f806c2c22204930837c44d81fdedfde079f" + integrity sha512-KRJtwrjRV5Bb+pM7zxcTJkhIqWWSy+MYsIxHK+0m5atcznsf15YwUBWHWulZerV2+vvHH1Lp1DD7pw6qKW8SgA== dependencies: web-streams-polyfill "^3.1.1" @@ -9754,7 +9757,7 @@ dependencies: "@types/node" "*" -"@types/cookie@^0.4.0", "@types/cookie@^0.4.1": +"@types/cookie@^0.4.1": version "0.4.1" resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q== @@ -15126,11 +15129,6 @@ cookie@0.7.1: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.1.tgz#2f73c42142d5d5cf71310a74fc4ae61670e5dbc9" integrity sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w== -cookie@^0.4.1: - version "0.4.2" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" - integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== - cookie@^0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" @@ -20520,13 +20518,6 @@ history@^4.6.0, history@^4.9.0: tiny-warning "^1.0.0" value-equal "^1.0.1" -history@^5.2.0, history@^5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/history/-/history-5.3.0.tgz#1548abaa245ba47992f063a0783db91ef201c73b" - integrity sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ== - dependencies: - "@babel/runtime" "^7.7.6" - hoist-non-react-statics@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz#aa448cf0986d55cc40773b17174b7dd066cb7cfb" @@ -22605,7 +22596,7 @@ jsesc@^2.5.1: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== -jsesc@^3.0.1, jsesc@^3.0.2: +jsesc@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.0.2.tgz#bb8b09a6597ba426425f2e4a07245c3d00b9343e" integrity sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g== @@ -28895,20 +28886,20 @@ react-is@^18.0.0: dependencies: "@remix-run/router" "1.21.0" -react-router-dom@^6.2.2: - version "6.3.0" - resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.3.0.tgz#a0216da813454e521905b5fa55e0e5176123f43d" - integrity sha512-uaJj7LKytRxZNQV8+RbzJWnJ8K2nPsOOEuX7aQstlMZKQT0164C+X2w6bnkqU3sjtLvpd5ojrezAyfZ1+0sStw== +react-router-dom@6.28.1: + version "6.28.1" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.28.1.tgz#b78fe452d2cd31919b80e57047a896bfa1509f8c" + integrity sha512-YraE27C/RdjcZwl5UCqF/ffXnZDxpJdk9Q6jw38SZHjXs7NNdpViq2l2c7fO7+4uWaEfcwfGCv3RSg4e1By/fQ== dependencies: - history "^5.2.0" - react-router "6.3.0" + "@remix-run/router" "1.21.0" + react-router "6.28.1" -react-router@6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.3.0.tgz#3970cc64b4cb4eae0c1ea5203a80334fdd175557" - integrity sha512-7Wh1DzVQ+tlFjkeo+ujvjSqSJmkt1+8JO+T5xklPlgrh70y7ogx75ODRW0ThWhY7S+6yEDks8TYrtQe/aoboBQ== +react-router@6.28.1: + version "6.28.1" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.28.1.tgz#f82317ab24eee67d7beb7b304c0378b2b48fa178" + integrity sha512-2omQTA3rkMljmrvvo6WtewGdVh45SpL9hGiCI9uUrwGGfNFDIvGK4gYJsKlJoNVi6AQZcopSCballL+QGOm7fA== dependencies: - history "^5.2.0" + "@remix-run/router" "1.21.0" react@^18.0.0: version "18.0.0" @@ -32590,6 +32581,11 @@ tunnel@^0.0.6: resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c" integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg== +turbo-stream@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/turbo-stream/-/turbo-stream-2.4.0.tgz#1e4fca6725e90fa14ac4adb782f2d3759a5695f0" + integrity sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g== + twirp-ts@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/twirp-ts/-/twirp-ts-2.5.0.tgz#b43f09e95868d68ecd5c755ecbb08a7e51388504" @@ -32889,6 +32885,11 @@ undici@^5.28.4: dependencies: "@fastify/busboy" "^2.0.0" +undici@^6.11.1: + version "6.21.0" + resolved "https://registry.yarnpkg.com/undici/-/undici-6.21.0.tgz#4b3d3afaef984e07b48e7620c34ed8a285ed4cd4" + integrity sha512-BUgJXc752Kou3oOIuU1i+yZZypyZRqNPW0vqoMPl8VaoalSfeR0D8/t4iAS3yirs79SSMTxTag+ZC86uswv+Cw== + unenv@^1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/unenv/-/unenv-1.10.0.tgz#c3394a6c6e4cfe68d699f87af456fe3f0db39571" From dc489e619c504a2bc798928d9d242431a457d10c Mon Sep 17 00:00:00 2001 From: Charly Gomez Date: Mon, 13 Jan 2025 14:30:13 +0100 Subject: [PATCH 02/16] remove version checks in utils --- packages/remix/src/utils/errors.ts | 41 +++++-------- packages/remix/src/utils/instrumentServer.ts | 60 ++++++-------------- 2 files changed, 29 insertions(+), 72 deletions(-) diff --git a/packages/remix/src/utils/errors.ts b/packages/remix/src/utils/errors.ts index 94c1c8755ad4..5beb9aa3406e 100644 --- a/packages/remix/src/utils/errors.ts +++ b/packages/remix/src/utils/errors.ts @@ -1,10 +1,14 @@ -import type { AppData, DataFunctionArgs, EntryContext, HandleDocumentRequestFunction } from '@remix-run/node'; +import type { + ActionFunctionArgs, + EntryContext, + HandleDocumentRequestFunction, + LoaderFunctionArgs, +} from '@remix-run/node'; import { addExceptionMechanism, captureException, getClient, handleCallbackErrors, - isPrimitive, logger, objectify, winterCGRequestToRequestData, @@ -22,19 +26,13 @@ import type { DataFunction, RemixRequest } from './vendor/types'; * @param err The error to capture. * @param name The name of the origin function. * @param request The request object. - * @param isRemixV2 Whether the error is from Remix v2 or not. Default is `true`. * * @returns A promise that resolves when the exception is captured. */ -export async function captureRemixServerException( - err: unknown, - name: string, - request: Request, - isRemixV2: boolean = true, -): Promise { +export async function captureRemixServerException(err: unknown, name: string, request: Request): Promise { // Skip capturing if the thrown error is not a 5xx response // https://remix.run/docs/en/v1/api/conventions#throwing-responses-in-loaders - if (isRemixV2 && isRouteErrorResponse(err) && err.status < 500) { + if (isRouteErrorResponse(err) && err.status < 500) { return; } @@ -82,7 +80,6 @@ export async function captureRemixServerException( * * @param origDocumentRequestFunction The original `HandleDocumentRequestFunction`. * @param requestContext The request context. - * @param isRemixV2 Whether the Remix version is v2 or not. * * @returns The wrapped `HandleDocumentRequestFunction`. */ @@ -96,7 +93,6 @@ export function errorHandleDocumentRequestFunction( context: EntryContext; loadContext?: Record; }, - isRemixV2: boolean, ): HandleDocumentRequestFunction { const { request, responseStatusCode, responseHeaders, context, loadContext } = requestContext; @@ -105,14 +101,6 @@ export function errorHandleDocumentRequestFunction( return origDocumentRequestFunction.call(this, request, responseStatusCode, responseHeaders, context, loadContext); }, err => { - // This exists to capture the server-side rendering errors on Remix v1 - // On Remix v2, we capture SSR errors at `handleError` - // We also skip primitives here, as we can't dedupe them, and also we don't expect any primitive SSR errors. - if (!isRemixV2 && !isPrimitive(err)) { - // eslint-disable-next-line @typescript-eslint/no-floating-promises - captureRemixServerException(err, 'documentRequest', request, isRemixV2); - } - throw err; }, ); @@ -125,7 +113,6 @@ export function errorHandleDocumentRequestFunction( * @param origFn The original `DataFunction`. * @param name The name of the function. * @param args The arguments of the function. - * @param isRemixV2 Whether the Remix version is v2 or not. * @param span The span to store the form data keys. * * @returns The wrapped `DataFunction`. @@ -134,10 +121,9 @@ export async function errorHandleDataFunction( this: unknown, origFn: DataFunction, name: string, - args: DataFunctionArgs, - isRemixV2: boolean, + args: ActionFunctionArgs | LoaderFunctionArgs, span?: Span, -): Promise { +): Promise { return handleCallbackErrors( async () => { if (name === 'action' && span) { @@ -151,12 +137,11 @@ export async function errorHandleDataFunction( return origFn.call(this, args); }, err => { - // On Remix v2, we capture all unexpected errors (except the `Route Error Response`s / Thrown Responses) in `handleError` function. + // We capture all unexpected errors (except the `Route Error Response`s / Thrown Responses) in `handleError` function. // This is both for consistency and also avoid duplicates such as primitives like `string` or `number` being captured twice. - // Remix v1 does not have a `handleError` function, so we capture all errors here. - if (isRemixV2 ? isResponse(err) : true) { + if (isResponse(err)) { // eslint-disable-next-line @typescript-eslint/no-floating-promises - captureRemixServerException(err, name, args.request, true); + captureRemixServerException(err, name, args.request); } throw err; diff --git a/packages/remix/src/utils/instrumentServer.ts b/packages/remix/src/utils/instrumentServer.ts index 1d67403209bc..0ea54986f55c 100644 --- a/packages/remix/src/utils/instrumentServer.ts +++ b/packages/remix/src/utils/instrumentServer.ts @@ -22,7 +22,6 @@ import { } from '@sentry/core'; import { DEBUG_BUILD } from './debug-build'; import { captureRemixServerException, errorHandleDataFunction, errorHandleDocumentRequestFunction } from './errors'; -import { getFutureFlagsServer, getRemixVersionFromBuild } from './futureFlags'; import type { RemixOptions } from './remixOptions'; import { createRoutes, getTransactionName } from './utils'; import { extractData, isDeferredData, isResponse, isRouteErrorResponse, json } from './vendor/response'; @@ -33,7 +32,6 @@ import type { DataFunction, DataFunctionArgs, EntryContext, - FutureConfig, HandleDocumentRequestFunction, RemixRequest, RequestHandler, @@ -42,8 +40,6 @@ import type { ServerRouteManifest, } from './vendor/types'; -let FUTURE_FLAGS: FutureConfig | undefined; - const redirectStatusCodes = new Set([301, 302, 303, 307, 308]); function isRedirectResponse(response: Response): boolean { return redirectStatusCodes.has(response.status); @@ -67,7 +63,6 @@ export function sentryHandleError(err: unknown, { request }: DataFunctionArgs): // We don't want to capture them twice. // This function is only for capturing unhandled server-side exceptions. // https://remix.run/docs/en/main/file-conventions/entry.server#thrown-responses - // https://remix.run/docs/en/v1/api/conventions#throwing-responses-in-loaders if (isResponse(err) || isRouteErrorResponse(err)) { return; } @@ -99,7 +94,7 @@ export function wrapHandleErrorWithSentry( }; } -function makeWrappedDocumentRequestFunction(autoInstrumentRemix?: boolean, remixVersion?: number) { +function makeWrappedDocumentRequestFunction(autoInstrumentRemix?: boolean) { return function (origDocumentRequestFunction: HandleDocumentRequestFunction): HandleDocumentRequestFunction { return async function ( this: unknown, @@ -117,8 +112,6 @@ function makeWrappedDocumentRequestFunction(autoInstrumentRemix?: boolean, remix loadContext, }; - const isRemixV2 = FUTURE_FLAGS?.v2_errorBoundary || remixVersion === 2; - if (!autoInstrumentRemix) { const activeSpan = getActiveSpan(); const rootSpan = activeSpan && getRootSpan(activeSpan); @@ -139,21 +132,11 @@ function makeWrappedDocumentRequestFunction(autoInstrumentRemix?: boolean, remix }, }, () => { - return errorHandleDocumentRequestFunction.call( - this, - origDocumentRequestFunction, - documentRequestContext, - isRemixV2, - ); + return errorHandleDocumentRequestFunction.call(this, origDocumentRequestFunction, documentRequestContext); }, ); } else { - return errorHandleDocumentRequestFunction.call( - this, - origDocumentRequestFunction, - documentRequestContext, - isRemixV2, - ); + return errorHandleDocumentRequestFunction.call(this, origDocumentRequestFunction, documentRequestContext); } }; }; @@ -163,12 +146,9 @@ function makeWrappedDataFunction( origFn: DataFunction, id: string, name: 'action' | 'loader', - remixVersion: number, autoInstrumentRemix?: boolean, ): DataFunction { return async function (this: unknown, args: DataFunctionArgs): Promise { - const isRemixV2 = FUTURE_FLAGS?.v2_errorBoundary || remixVersion === 2; - if (!autoInstrumentRemix) { return startSpan( { @@ -180,25 +160,25 @@ function makeWrappedDataFunction( }, }, (span: Span) => { - return errorHandleDataFunction.call(this, origFn, name, args, isRemixV2, span); + return errorHandleDataFunction.call(this, origFn, name, args, span); }, ); } else { - return errorHandleDataFunction.call(this, origFn, name, args, isRemixV2); + return errorHandleDataFunction.call(this, origFn, name, args); } }; } const makeWrappedAction = - (id: string, remixVersion: number, autoInstrumentRemix?: boolean) => + (id: string, autoInstrumentRemix?: boolean) => (origAction: DataFunction): DataFunction => { - return makeWrappedDataFunction(origAction, id, 'action', remixVersion, autoInstrumentRemix); + return makeWrappedDataFunction(origAction, id, 'action', autoInstrumentRemix); }; const makeWrappedLoader = - (id: string, remixVersion: number, autoInstrumentRemix?: boolean) => + (id: string, autoInstrumentRemix?: boolean) => (origLoader: DataFunction): DataFunction => { - return makeWrappedDataFunction(origLoader, id, 'loader', remixVersion, autoInstrumentRemix); + return makeWrappedDataFunction(origLoader, id, 'loader', autoInstrumentRemix); }; function getTraceAndBaggage(): { @@ -217,7 +197,7 @@ function getTraceAndBaggage(): { return {}; } -function makeWrappedRootLoader(remixVersion: number) { +function makeWrappedRootLoader() { return function (origLoader: DataFunction): DataFunction { return async function (this: unknown, args: DataFunctionArgs): Promise { const res = await origLoader.call(this, args); @@ -226,7 +206,6 @@ function makeWrappedRootLoader(remixVersion: number) { if (isDeferredData(res)) { res.data['sentryTrace'] = traceAndBaggage.sentryTrace; res.data['sentryBaggage'] = traceAndBaggage.sentryBaggage; - res.data['remixVersion'] = remixVersion; return res; } @@ -243,7 +222,7 @@ function makeWrappedRootLoader(remixVersion: number) { if (typeof data === 'object') { return json( - { ...data, ...traceAndBaggage, remixVersion }, + { ...data, ...traceAndBaggage }, { headers: res.headers, statusText: res.statusText, @@ -257,7 +236,7 @@ function makeWrappedRootLoader(remixVersion: number) { } } - return { ...res, ...traceAndBaggage, remixVersion }; + return { ...res, ...traceAndBaggage }; }; }; } @@ -351,7 +330,6 @@ function wrapRequestHandler( function instrumentBuildCallback(build: ServerBuild, autoInstrumentRemix: boolean): ServerBuild { const routes: ServerRouteManifest = {}; - const remixVersion = getRemixVersionFromBuild(build); const wrappedEntry = { ...build.entry, module: { ...build.entry.module } }; // Not keeping boolean flags like it's done for `requestHandler` functions, @@ -360,7 +338,7 @@ function instrumentBuildCallback(build: ServerBuild, autoInstrumentRemix: boolea // We should be able to wrap them, as they may not be wrapped before. const defaultExport = wrappedEntry.module.default as undefined | WrappedFunction; if (defaultExport && !defaultExport.__sentry_original__) { - fill(wrappedEntry.module, 'default', makeWrappedDocumentRequestFunction(autoInstrumentRemix, remixVersion)); + fill(wrappedEntry.module, 'default', makeWrappedDocumentRequestFunction(autoInstrumentRemix)); } for (const [id, route] of Object.entries(build.routes)) { @@ -368,12 +346,12 @@ function instrumentBuildCallback(build: ServerBuild, autoInstrumentRemix: boolea const routeAction = wrappedRoute.module.action as undefined | WrappedFunction; if (routeAction && !routeAction.__sentry_original__) { - fill(wrappedRoute.module, 'action', makeWrappedAction(id, remixVersion, autoInstrumentRemix)); + fill(wrappedRoute.module, 'action', makeWrappedAction(id, autoInstrumentRemix)); } const routeLoader = wrappedRoute.module.loader as undefined | WrappedFunction; if (routeLoader && !routeLoader.__sentry_original__) { - fill(wrappedRoute.module, 'loader', makeWrappedLoader(id, remixVersion, autoInstrumentRemix)); + fill(wrappedRoute.module, 'loader', makeWrappedLoader(id, autoInstrumentRemix)); } // Entry module should have a loader function to provide `sentry-trace` and `baggage` @@ -384,7 +362,7 @@ function instrumentBuildCallback(build: ServerBuild, autoInstrumentRemix: boolea } // We want to wrap the root loader regardless of whether it's already wrapped before. - fill(wrappedRoute.module, 'loader', makeWrappedRootLoader(remixVersion)); + fill(wrappedRoute.module, 'loader', makeWrappedRootLoader()); } routes[id] = wrappedRoute; @@ -409,19 +387,13 @@ export function instrumentBuild( if (resolvedBuild instanceof Promise) { return resolvedBuild.then(build => { - FUTURE_FLAGS = getFutureFlagsServer(build); - return instrumentBuildCallback(build, autoInstrumentRemix); }); } else { - FUTURE_FLAGS = getFutureFlagsServer(resolvedBuild); - return instrumentBuildCallback(resolvedBuild, autoInstrumentRemix); } }; } else { - FUTURE_FLAGS = getFutureFlagsServer(build); - return instrumentBuildCallback(build, autoInstrumentRemix); } } From a1a303982e59854c314e2c44899764931799ae0c Mon Sep 17 00:00:00 2001 From: Charly Gomez Date: Mon, 13 Jan 2025 14:49:29 +0100 Subject: [PATCH 03/16] remove version checks for client utils --- packages/remix/src/client/performance.tsx | 36 ++--------------------- 1 file changed, 3 insertions(+), 33 deletions(-) diff --git a/packages/remix/src/client/performance.tsx b/packages/remix/src/client/performance.tsx index 32c6226e463e..90520381dfcd 100644 --- a/packages/remix/src/client/performance.tsx +++ b/packages/remix/src/client/performance.tsx @@ -8,21 +8,10 @@ import { isNodeEnv, logger, } from '@sentry/core'; -import type { - BrowserClient, - ErrorBoundaryProps, - browserTracingIntegration as originalBrowserTracingIntegration, -} from '@sentry/react'; -import { - WINDOW, - getClient, - startBrowserTracingNavigationSpan, - startBrowserTracingPageLoadSpan, - withErrorBoundary, -} from '@sentry/react'; +import type { BrowserClient, browserTracingIntegration as originalBrowserTracingIntegration } from '@sentry/react'; +import { WINDOW, getClient, startBrowserTracingNavigationSpan, startBrowserTracingPageLoadSpan } from '@sentry/react'; import * as React from 'react'; import { DEBUG_BUILD } from '../utils/debug-build'; -import { getFutureFlagsBrowser, readRemixVersionFromLoader } from '../utils/futureFlags'; export type Params = { readonly [key in Key]: string | undefined; @@ -66,10 +55,6 @@ function getInitPathName(): string | undefined { return undefined; } -function isRemixV2(remixVersion: number | undefined): boolean { - return remixVersion === 2 || getFutureFlagsBrowser()?.v2_errorBoundary || false; -} - export function startPageloadSpan(client: Client): void { const initPathName = getInitPathName(); @@ -118,17 +103,7 @@ function startNavigationSpan(matches: RouteMatch[]): void { * @param OrigApp The Remix root to wrap * @param options The options for ErrorBoundary wrapper. */ -export function withSentry

, R extends React.ComponentType

>( - OrigApp: R, - options: { - wrapWithErrorBoundary?: boolean; - errorBoundaryOptions?: ErrorBoundaryProps; - } = { - // We don't want to wrap application with Sentry's ErrorBoundary by default for Remix v2 - wrapWithErrorBoundary: true, - errorBoundaryOptions: {}, - }, -): R { +export function withSentry

, R extends React.ComponentType

>(OrigApp: R): R { const SentryRoot: React.FC

= (props: P) => { // Early return when any of the required functions is not available. if (!_useEffect || !_useLocation || !_useMatches) { @@ -188,11 +163,6 @@ export function withSentry

, R extends React.Co isBaseLocation = false; - if (!isRemixV2(readRemixVersionFromLoader()) && options.wrapWithErrorBoundary) { - // @ts-expect-error Setting more specific React Component typing for `R` generic above - // will break advanced type inference done by react router params - return withErrorBoundary(OrigApp, options.errorBoundaryOptions)(props); - } // @ts-expect-error Setting more specific React Component typing for `R` generic above // will break advanced type inference done by react router params return ; From b43ffc4c98f8da41090c1ae1dbdac3621943196c Mon Sep 17 00:00:00 2001 From: Charly Gomez Date: Mon, 13 Jan 2025 14:49:43 +0100 Subject: [PATCH 04/16] remove unused feature flag utils --- packages/remix/src/utils/futureFlags.ts | 67 ------------------------- 1 file changed, 67 deletions(-) delete mode 100644 packages/remix/src/utils/futureFlags.ts diff --git a/packages/remix/src/utils/futureFlags.ts b/packages/remix/src/utils/futureFlags.ts deleted file mode 100644 index 63c9c5dff2ef..000000000000 --- a/packages/remix/src/utils/futureFlags.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { GLOBAL_OBJ } from '@sentry/core'; - -import type { FutureConfig, ServerBuild } from './vendor/types'; - -export type EnhancedGlobal = typeof GLOBAL_OBJ & { - __remixContext?: { - future?: FutureConfig; - state?: { - loaderData?: { - root?: { - remixVersion?: number; - }; - }; - }; - }; -}; - -/** - * Get the future flags from the Remix browser context - * - * @returns The future flags - */ -export function getFutureFlagsBrowser(): FutureConfig | undefined { - const window = GLOBAL_OBJ as EnhancedGlobal; - - if (!window.__remixContext) { - return; - } - - return window.__remixContext.future; -} - -/** - * Get the future flags from the Remix server build - * - * @param build The Remix server build - * - * @returns The future flags - */ -export function getFutureFlagsServer(build: ServerBuild): FutureConfig | undefined { - return build.future; -} - -/** - * Learn Remix version from the server build object - * V2 Server builds have a non-optional `mode` property - * - * @returns The major version number - */ -export function getRemixVersionFromBuild(build: ServerBuild): number { - if ('mode' in build) { - return 2; - } - - return 1; -} - -/** - * Read Remix version from the Remix context on the browser - * - * @returns The major version number - */ -export function readRemixVersionFromLoader(): number | undefined { - const window = GLOBAL_OBJ as EnhancedGlobal; - - return window.__remixContext?.state?.loaderData?.root?.remixVersion; -} From 46e834bb157a65488ee39ccb9626cc9e922ec165 Mon Sep 17 00:00:00 2001 From: Charly Gomez Date: Tue, 14 Jan 2025 19:07:21 +0100 Subject: [PATCH 05/16] update integration tests --- .github/workflows/build.yml | 2 - packages/remix/package.json | 7 +- packages/remix/playwright.config.ts | 5 +- .../test/integration/app_v1/entry.client.tsx | 18 ------ .../test/integration/app_v1/entry.server.tsx | 23 ------- .../remix/test/integration/app_v1/root.tsx | 64 ------------------- .../routes/action-json-response/$id.tsx | 2 - .../app_v1/routes/capture-exception.tsx | 2 - .../app_v1/routes/capture-message.tsx | 2 - .../routes/error-boundary-capture/$id.tsx | 2 - .../test/integration/app_v1/routes/index.tsx | 2 - .../routes/loader-defer-response/$id.tsx | 2 - .../routes/loader-json-response/$id.tsx | 2 - .../routes/loader-throw-response/$id.tsx | 2 - .../app_v1/routes/manual-tracing/$id.tsx | 2 - .../app_v1/routes/scope-bleed/$id.tsx | 2 - .../server-side-unexpected-errors/$id.tsx | 2 - .../integration/app_v1/routes/ssr-error.tsx | 2 - .../app_v1/routes/throw-redirect.tsx | 2 - .../test/integration/app_v2/entry.server.tsx | 11 +++- .../remix/test/integration/app_v2/root.tsx | 8 +-- .../test/integration/instrument.server.cjs | 2 +- packages/remix/test/integration/package.json | 21 +++--- .../remix/test/integration/remix.config.js | 12 +--- .../test/client/click-error.test.ts | 7 -- .../test/client/errorboundary.test.ts | 28 ++------ .../test/client/manualtracing.test.ts | 4 +- .../integration/test/client/pageload.test.ts | 4 +- .../instrumentation-legacy/action.test.ts | 36 +++++------ .../instrumentation-legacy/loader.test.ts | 61 +++++++----------- .../server/instrumentation-legacy/ssr.test.ts | 14 ++-- .../instrumentation-otel/action.test.ts | 14 ++-- .../instrumentation-otel/loader.test.ts | 8 +-- .../server/instrumentation-otel/ssr.test.ts | 14 ++-- packages/remix/test/integration/tsconfig.json | 2 +- 35 files changed, 96 insertions(+), 295 deletions(-) delete mode 100644 packages/remix/test/integration/app_v1/entry.client.tsx delete mode 100644 packages/remix/test/integration/app_v1/entry.server.tsx delete mode 100644 packages/remix/test/integration/app_v1/root.tsx delete mode 100644 packages/remix/test/integration/app_v1/routes/action-json-response/$id.tsx delete mode 100644 packages/remix/test/integration/app_v1/routes/capture-exception.tsx delete mode 100644 packages/remix/test/integration/app_v1/routes/capture-message.tsx delete mode 100644 packages/remix/test/integration/app_v1/routes/error-boundary-capture/$id.tsx delete mode 100644 packages/remix/test/integration/app_v1/routes/index.tsx delete mode 100644 packages/remix/test/integration/app_v1/routes/loader-defer-response/$id.tsx delete mode 100644 packages/remix/test/integration/app_v1/routes/loader-json-response/$id.tsx delete mode 100644 packages/remix/test/integration/app_v1/routes/loader-throw-response/$id.tsx delete mode 100644 packages/remix/test/integration/app_v1/routes/manual-tracing/$id.tsx delete mode 100644 packages/remix/test/integration/app_v1/routes/scope-bleed/$id.tsx delete mode 100644 packages/remix/test/integration/app_v1/routes/server-side-unexpected-errors/$id.tsx delete mode 100644 packages/remix/test/integration/app_v1/routes/ssr-error.tsx delete mode 100644 packages/remix/test/integration/app_v1/routes/throw-redirect.tsx diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f3cb91c0f376..8414ee66f52c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -756,7 +756,6 @@ jobs: fail-fast: false matrix: node: [18, 20, 22] - remix: [1, 2] steps: - name: Check out current commit (${{ needs.job_get_metadata.outputs.commit_label }}) uses: actions/checkout@v4 @@ -779,7 +778,6 @@ jobs: - name: Run integration tests env: NODE_VERSION: ${{ matrix.node }} - REMIX_VERSION: ${{ matrix.remix }} run: | cd packages/remix yarn test:integration:ci diff --git a/packages/remix/package.json b/packages/remix/package.json index 6706937895c7..d5df414b6f7f 100644 --- a/packages/remix/package.json +++ b/packages/remix/package.json @@ -93,10 +93,9 @@ "lint": "eslint . --format stylish", "test": "yarn test:unit", "test:integration": "run-s test:integration:otel test:integration:legacy", - "test:integration:otel": "export USE_OTEL=1 && run-s test:integration:v1 test:integration:v2", - "test:integration:legacy": "export USE_OTEL=0 && run-s test:integration:v1 test:integration:v2", - "test:integration:v1": "run-s test:integration:clean test:integration:prepare test:integration:client test:integration:server", - "test:integration:v2": "export REMIX_VERSION=2 && yarn test:integration:v1", + "test:integration:otel": "export USE_OTEL=1 && yarn test:integration:v2", + "test:integration:legacy": "export USE_OTEL=0 && yarn test:integration:v2", + "test:integration:v2": "run-s test:integration:clean test:integration:prepare test:integration:client test:integration:server", "test:integration:ci": "run-s test:integration:ci:otel test:integration:ci:legacy", "test:integration:ci:otel": "USE_OTEL=1 yarn test:integration:ci:common", "test:integration:ci:legacy": "USE_OTEL=0 yarn test:integration:ci:common", diff --git a/packages/remix/playwright.config.ts b/packages/remix/playwright.config.ts index 142272a44740..6e9fde329fd3 100644 --- a/packages/remix/playwright.config.ts +++ b/packages/remix/playwright.config.ts @@ -13,10 +13,7 @@ const config: PlaywrightTestConfig = { // Note that 3 is a random number selected to work well with our CI setup workers: process.env.CI ? 3 : undefined, webServer: { - env: { - NODE_OPTIONS: process.env.USE_OTEL === '1' ? '--require ./instrument.server.cjs' : '', - }, - command: '(cd test/integration/ && yarn build && yarn start)', + command: `(cd test/integration/ && yarn build && yarn ${process.env.USE_OTEL === '1' ? 'start:otel' : 'start'})`, port: 3000, }, projects: [ diff --git a/packages/remix/test/integration/app_v1/entry.client.tsx b/packages/remix/test/integration/app_v1/entry.client.tsx deleted file mode 100644 index bdee1860d03f..000000000000 --- a/packages/remix/test/integration/app_v1/entry.client.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { RemixBrowser, useLocation, useMatches } from '@remix-run/react'; -import * as Sentry from '@sentry/remix'; -import { useEffect } from 'react'; -import { hydrate } from 'react-dom'; - -Sentry.init({ - dsn: 'https://public@dsn.ingest.sentry.io/1337', - tracesSampleRate: 1, - integrations: [ - Sentry.browserTracingIntegration({ - useEffect, - useLocation, - useMatches, - }), - ], -}); - -hydrate(, document); diff --git a/packages/remix/test/integration/app_v1/entry.server.tsx b/packages/remix/test/integration/app_v1/entry.server.tsx deleted file mode 100644 index 9ecf5f467588..000000000000 --- a/packages/remix/test/integration/app_v1/entry.server.tsx +++ /dev/null @@ -1,23 +0,0 @@ -if (process.env.USE_OTEL !== '1') { - require('../instrument.server.cjs'); -} - -import type { EntryContext } from '@remix-run/node'; -import { RemixServer } from '@remix-run/react'; -import { renderToString } from 'react-dom/server'; - -export default function handleRequest( - request: Request, - responseStatusCode: number, - responseHeaders: Headers, - remixContext: EntryContext, -) { - let markup = renderToString(); - - responseHeaders.set('Content-Type', 'text/html'); - - return new Response('' + markup, { - status: responseStatusCode, - headers: responseHeaders, - }); -} diff --git a/packages/remix/test/integration/app_v1/root.tsx b/packages/remix/test/integration/app_v1/root.tsx deleted file mode 100644 index 51dcb00c4e8f..000000000000 --- a/packages/remix/test/integration/app_v1/root.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import { LoaderFunction, MetaFunction, defer, json, redirect } from '@remix-run/node'; -import { Links, LiveReload, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react'; -import { withSentry } from '@sentry/remix'; - -export const meta: MetaFunction = ({ data }) => ({ - charset: 'utf-8', - title: 'New Remix App', - viewport: 'width=device-width,initial-scale=1', - 'sentry-trace': data.sentryTrace, - baggage: data.sentryBaggage, -}); - -export const loader: LoaderFunction = async ({ request }) => { - const url = new URL(request.url); - const type = url.searchParams.get('type'); - - switch (type) { - case 'empty': - return {}; - case 'plain': - return { - data_one: [], - data_two: 'a string', - }; - case 'json': - return json({ data_one: [], data_two: 'a string' }, { headers: { 'Cache-Control': 'max-age=300' } }); - case 'defer': - return defer({ data_one: [], data_two: 'a string' }); - case 'null': - return null; - case 'undefined': - return undefined; - case 'throwRedirect': - throw redirect('/?type=plain'); - case 'returnRedirect': - return redirect('/?type=plain'); - case 'throwRedirectToExternal': - throw redirect('https://example.com'); - case 'returnRedirectToExternal': - return redirect('https://example.com'); - default: { - return {}; - } - } -}; - -function App() { - return ( - - - - - - - - - - - - - ); -} - -export default withSentry(App); diff --git a/packages/remix/test/integration/app_v1/routes/action-json-response/$id.tsx b/packages/remix/test/integration/app_v1/routes/action-json-response/$id.tsx deleted file mode 100644 index ed034a14c52a..000000000000 --- a/packages/remix/test/integration/app_v1/routes/action-json-response/$id.tsx +++ /dev/null @@ -1,2 +0,0 @@ -export * from '../../../common/routes/action-json-response.$id'; -export { default } from '../../../common/routes/action-json-response.$id'; diff --git a/packages/remix/test/integration/app_v1/routes/capture-exception.tsx b/packages/remix/test/integration/app_v1/routes/capture-exception.tsx deleted file mode 100644 index 1ba745d2e63d..000000000000 --- a/packages/remix/test/integration/app_v1/routes/capture-exception.tsx +++ /dev/null @@ -1,2 +0,0 @@ -export * from '../../common/routes/capture-exception'; -export { default } from '../../common/routes/capture-exception'; diff --git a/packages/remix/test/integration/app_v1/routes/capture-message.tsx b/packages/remix/test/integration/app_v1/routes/capture-message.tsx deleted file mode 100644 index 9dae2318cc14..000000000000 --- a/packages/remix/test/integration/app_v1/routes/capture-message.tsx +++ /dev/null @@ -1,2 +0,0 @@ -export * from '../../common/routes/capture-message'; -export { default } from '../../common/routes/capture-message'; diff --git a/packages/remix/test/integration/app_v1/routes/error-boundary-capture/$id.tsx b/packages/remix/test/integration/app_v1/routes/error-boundary-capture/$id.tsx deleted file mode 100644 index 2c287dfe9696..000000000000 --- a/packages/remix/test/integration/app_v1/routes/error-boundary-capture/$id.tsx +++ /dev/null @@ -1,2 +0,0 @@ -export * from '../../../common/routes/error-boundary-capture.$id'; -export { default } from '../../../common/routes/error-boundary-capture.$id'; diff --git a/packages/remix/test/integration/app_v1/routes/index.tsx b/packages/remix/test/integration/app_v1/routes/index.tsx deleted file mode 100644 index 22c086a4c2cf..000000000000 --- a/packages/remix/test/integration/app_v1/routes/index.tsx +++ /dev/null @@ -1,2 +0,0 @@ -export * from '../../common/routes/index'; -export { default } from '../../common/routes/index'; diff --git a/packages/remix/test/integration/app_v1/routes/loader-defer-response/$id.tsx b/packages/remix/test/integration/app_v1/routes/loader-defer-response/$id.tsx deleted file mode 100644 index f0c19208a85f..000000000000 --- a/packages/remix/test/integration/app_v1/routes/loader-defer-response/$id.tsx +++ /dev/null @@ -1,2 +0,0 @@ -export * from '../../../common/routes/loader-defer-response.$id'; -export { default } from '../../../common/routes/loader-defer-response.$id'; diff --git a/packages/remix/test/integration/app_v1/routes/loader-json-response/$id.tsx b/packages/remix/test/integration/app_v1/routes/loader-json-response/$id.tsx deleted file mode 100644 index ddf33953d77d..000000000000 --- a/packages/remix/test/integration/app_v1/routes/loader-json-response/$id.tsx +++ /dev/null @@ -1,2 +0,0 @@ -export * from '../../../common/routes/loader-json-response.$id'; -export { default } from '../../../common/routes/loader-json-response.$id'; diff --git a/packages/remix/test/integration/app_v1/routes/loader-throw-response/$id.tsx b/packages/remix/test/integration/app_v1/routes/loader-throw-response/$id.tsx deleted file mode 100644 index 0b9850f50287..000000000000 --- a/packages/remix/test/integration/app_v1/routes/loader-throw-response/$id.tsx +++ /dev/null @@ -1,2 +0,0 @@ -export * from '../../../common/routes/loader-throw-response.$id'; -export { default } from '../../../common/routes/loader-throw-response.$id'; diff --git a/packages/remix/test/integration/app_v1/routes/manual-tracing/$id.tsx b/packages/remix/test/integration/app_v1/routes/manual-tracing/$id.tsx deleted file mode 100644 index 9979714818ff..000000000000 --- a/packages/remix/test/integration/app_v1/routes/manual-tracing/$id.tsx +++ /dev/null @@ -1,2 +0,0 @@ -export * from '../../../common/routes/manual-tracing.$id'; -export { default } from '../../../common/routes/manual-tracing.$id'; diff --git a/packages/remix/test/integration/app_v1/routes/scope-bleed/$id.tsx b/packages/remix/test/integration/app_v1/routes/scope-bleed/$id.tsx deleted file mode 100644 index d86864dccb9b..000000000000 --- a/packages/remix/test/integration/app_v1/routes/scope-bleed/$id.tsx +++ /dev/null @@ -1,2 +0,0 @@ -export * from '../../../common/routes/scope-bleed.$id'; -export { default } from '../../../common/routes/scope-bleed.$id'; diff --git a/packages/remix/test/integration/app_v1/routes/server-side-unexpected-errors/$id.tsx b/packages/remix/test/integration/app_v1/routes/server-side-unexpected-errors/$id.tsx deleted file mode 100644 index fc595b18c3b3..000000000000 --- a/packages/remix/test/integration/app_v1/routes/server-side-unexpected-errors/$id.tsx +++ /dev/null @@ -1,2 +0,0 @@ -export * from '../../../common/routes/server-side-unexpected-errors.$id'; -export { default } from '../../../common/routes/server-side-unexpected-errors.$id'; diff --git a/packages/remix/test/integration/app_v1/routes/ssr-error.tsx b/packages/remix/test/integration/app_v1/routes/ssr-error.tsx deleted file mode 100644 index 627f7e126871..000000000000 --- a/packages/remix/test/integration/app_v1/routes/ssr-error.tsx +++ /dev/null @@ -1,2 +0,0 @@ -export * from '../../common/routes/ssr-error'; -export { default } from '../../common/routes/ssr-error'; diff --git a/packages/remix/test/integration/app_v1/routes/throw-redirect.tsx b/packages/remix/test/integration/app_v1/routes/throw-redirect.tsx deleted file mode 100644 index 4425f3432b58..000000000000 --- a/packages/remix/test/integration/app_v1/routes/throw-redirect.tsx +++ /dev/null @@ -1,2 +0,0 @@ -export * from '../../common/routes/throw-redirect'; -export { default } from '../../common/routes/throw-redirect'; diff --git a/packages/remix/test/integration/app_v2/entry.server.tsx b/packages/remix/test/integration/app_v2/entry.server.tsx index 968ec19a5f59..f7ca9d82345a 100644 --- a/packages/remix/test/integration/app_v2/entry.server.tsx +++ b/packages/remix/test/integration/app_v2/entry.server.tsx @@ -1,9 +1,14 @@ +import * as Sentry from '@sentry/remix'; + if (process.env.USE_OTEL !== '1') { - require('../instrument.server.cjs'); + Sentry.init({ + dsn: 'https://public@dsn.ingest.sentry.io/1337', + tracesSampleRate: 1, + tracePropagationTargets: ['example.org'], + autoInstrumentRemix: false, + }); } -import * as Sentry from '@sentry/remix'; - import type { EntryContext } from '@remix-run/node'; import { RemixServer } from '@remix-run/react'; import { renderToString } from 'react-dom/server'; diff --git a/packages/remix/test/integration/app_v2/root.tsx b/packages/remix/test/integration/app_v2/root.tsx index 399136e04089..1b8e5e39e8f5 100644 --- a/packages/remix/test/integration/app_v2/root.tsx +++ b/packages/remix/test/integration/app_v2/root.tsx @@ -1,9 +1,9 @@ -import { LoaderFunction, V2_MetaFunction, defer, json, redirect } from '@remix-run/node'; +import { LoaderFunction, MetaFunction, defer, json, redirect } from '@remix-run/node'; import { Links, LiveReload, Meta, Outlet, Scripts, ScrollRestoration, useRouteError } from '@remix-run/react'; -import { V2_ErrorBoundaryComponent } from '@remix-run/react/dist/routeModules'; +import { ErrorBoundaryComponent } from '@remix-run/react/dist/routeModules'; import { captureRemixErrorBoundaryError, withSentry } from '@sentry/remix'; -export const ErrorBoundary: V2_ErrorBoundaryComponent = () => { +export const ErrorBoundary: ErrorBoundaryComponent = () => { const error = useRouteError(); captureRemixErrorBoundaryError(error); @@ -15,7 +15,7 @@ export const ErrorBoundary: V2_ErrorBoundaryComponent = () => { ); }; -export const meta: V2_MetaFunction = ({ data }) => [ +export const meta: MetaFunction = ({ data }) => [ { charset: 'utf-8' }, { title: 'New Remix App' }, { name: 'viewport', content: 'width=device-width,initial-scale=1' }, diff --git a/packages/remix/test/integration/instrument.server.cjs b/packages/remix/test/integration/instrument.server.cjs index d33b155f2d50..32d6319fe52b 100644 --- a/packages/remix/test/integration/instrument.server.cjs +++ b/packages/remix/test/integration/instrument.server.cjs @@ -4,5 +4,5 @@ Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', tracesSampleRate: 1, tracePropagationTargets: ['example.org'], - autoInstrumentRemix: process.env.USE_OTEL === '1', + autoInstrumentRemix: true, }); diff --git a/packages/remix/test/integration/package.json b/packages/remix/test/integration/package.json index 13d66600bedd..ed54981fb790 100644 --- a/packages/remix/test/integration/package.json +++ b/packages/remix/test/integration/package.json @@ -4,21 +4,22 @@ "scripts": { "build": "remix build", "dev": "remix dev", - "start": "remix-serve build" + "start": "remix-serve build/index.js", + "start:otel": "NODE_OPTIONS='--require=./instrument.server.cjs' remix-serve build/index.js" }, "dependencies": { - "@remix-run/express": "1.17.0", - "@remix-run/node": "1.17.0", - "@remix-run/react": "1.17.0", - "@remix-run/serve": "1.17.0", + "@remix-run/express": "2.15.2", + "@remix-run/node": "2.15.2", + "@remix-run/react": "2.15.2", + "@remix-run/serve": "2.15.2", "@sentry/remix": "file:../..", - "react": "^17.0.2", - "react-dom": "^17.0.2" + "react": "^18", + "react-dom": "^18" }, "devDependencies": { - "@remix-run/dev": "1.17.0", - "@types/react": "^17.0.47", - "@types/react-dom": "^17.0.17", + "@remix-run/dev": "2.15.2", + "@types/react": "^18", + "@types/react-dom": "^18", "nock": "^13.5.5", "typescript": "~5.0.0" }, diff --git a/packages/remix/test/integration/remix.config.js b/packages/remix/test/integration/remix.config.js index b4c7ac0837b8..6280bed5e827 100644 --- a/packages/remix/test/integration/remix.config.js +++ b/packages/remix/test/integration/remix.config.js @@ -1,16 +1,8 @@ /** @type {import('@remix-run/dev').AppConfig} */ -const useV2 = process.env.REMIX_VERSION === '2'; - module.exports = { - appDirectory: useV2 ? 'app_v2' : 'app_v1', + appDirectory: 'app_v2', assetsBuildDirectory: 'public/build', serverBuildPath: 'build/index.js', publicPath: '/build/', - future: { - v2_errorBoundary: useV2, - v2_headers: useV2, - v2_meta: useV2, - v2_normalizeFormMethod: useV2, - v2_routeConvention: useV2, - }, + serverModuleFormat: 'cjs', }; diff --git a/packages/remix/test/integration/test/client/click-error.test.ts b/packages/remix/test/integration/test/client/click-error.test.ts index f9e895b3a8f2..a6385c0e0963 100644 --- a/packages/remix/test/integration/test/client/click-error.test.ts +++ b/packages/remix/test/integration/test/client/click-error.test.ts @@ -2,14 +2,7 @@ import { expect, test } from '@playwright/test'; import { Event } from '@sentry/core'; import { getMultipleSentryEnvelopeRequests } from './utils/helpers'; -const useV2 = process.env.REMIX_VERSION === '2'; - test('should report a manually captured message on click with the correct stacktrace.', async ({ page }) => { - if (!useV2) { - test.skip(); - return; - } - await page.goto('/click-error'); const promise = getMultipleSentryEnvelopeRequests(page, 2); diff --git a/packages/remix/test/integration/test/client/errorboundary.test.ts b/packages/remix/test/integration/test/client/errorboundary.test.ts index c679f736ea8e..6076cee2ced5 100644 --- a/packages/remix/test/integration/test/client/errorboundary.test.ts +++ b/packages/remix/test/integration/test/client/errorboundary.test.ts @@ -2,8 +2,6 @@ import { expect, test } from '@playwright/test'; import { Event } from '@sentry/core'; import { getMultipleSentryEnvelopeRequests } from './utils/helpers'; -const useV2 = process.env.REMIX_VERSION === '2'; - test('should capture React component errors.', async ({ page }) => { const envelopes = await getMultipleSentryEnvelopeRequests(page, 2, { url: '/error-boundary-capture/0', @@ -13,38 +11,22 @@ test('should capture React component errors.', async ({ page }) => { expect(pageloadEnvelope.contexts?.trace?.op).toBe('pageload'); expect(pageloadEnvelope.type).toBe('transaction'); - expect(pageloadEnvelope.transaction).toBe( - useV2 ? 'routes/error-boundary-capture.$id' : 'routes/error-boundary-capture/$id', - ); + expect(pageloadEnvelope.transaction).toBe('routes/error-boundary-capture.$id'); expect(errorEnvelope.level).toBe('error'); expect(errorEnvelope.sdk?.name).toBe('sentry.javascript.remix'); expect(errorEnvelope.exception?.values).toMatchObject([ - ...(!useV2 - ? [ - { - type: 'React ErrorBoundary Error', - value: 'Sentry React Component Error', - stacktrace: { frames: expect.any(Array) }, - mechanism: { type: 'chained', handled: false }, - }, - ] - : []), { type: 'Error', value: 'Sentry React Component Error', stacktrace: { frames: expect.any(Array) }, // In v2 this error will be marked unhandled, in v1 its handled because of LinkedErrors // This should be fine though because the error boundary's error is marked unhandled - mechanism: { type: useV2 ? 'instrument' : 'generic', handled: !useV2 }, + mechanism: { type: 'instrument', handled: false }, }, ]); - expect(errorEnvelope.transaction).toBe( - useV2 ? 'routes/error-boundary-capture.$id' : 'routes/error-boundary-capture/$id', - ); + expect(errorEnvelope.transaction).toBe('routes/error-boundary-capture.$id'); - if (useV2) { - // The error boundary should be rendered - expect(await page.textContent('#error-header')).toBe('ErrorBoundary Error'); - } + // The error boundary should be rendered + expect(await page.textContent('#error-header')).toBe('ErrorBoundary Error'); }); diff --git a/packages/remix/test/integration/test/client/manualtracing.test.ts b/packages/remix/test/integration/test/client/manualtracing.test.ts index 01ae4cf66521..ff2bcac3ec1c 100644 --- a/packages/remix/test/integration/test/client/manualtracing.test.ts +++ b/packages/remix/test/integration/test/client/manualtracing.test.ts @@ -2,8 +2,6 @@ import { expect, test } from '@playwright/test'; import { Event } from '@sentry/core'; import { getMultipleSentryEnvelopeRequests } from './utils/helpers'; -const useV2 = process.env.REMIX_VERSION === '2'; - test('should report a manually created / finished transaction.', async ({ page }) => { const envelopes = await getMultipleSentryEnvelopeRequests(page, 2, { url: '/manual-tracing/0', @@ -19,5 +17,5 @@ test('should report a manually created / finished transaction.', async ({ page } expect(pageloadEnvelope.contexts?.trace?.op).toBe('pageload'); expect(pageloadEnvelope.type).toBe('transaction'); - expect(pageloadEnvelope.transaction).toBe(useV2 ? 'routes/manual-tracing.$id' : 'routes/manual-tracing/$id'); + expect(pageloadEnvelope.transaction).toBe('routes/manual-tracing.$id'); }); diff --git a/packages/remix/test/integration/test/client/pageload.test.ts b/packages/remix/test/integration/test/client/pageload.test.ts index bf45a512fabe..55e97e23635f 100644 --- a/packages/remix/test/integration/test/client/pageload.test.ts +++ b/packages/remix/test/integration/test/client/pageload.test.ts @@ -1,5 +1,3 @@ -const useV2 = process.env.REMIX_VERSION === '2'; - import { expect, test } from '@playwright/test'; import { Event } from '@sentry/core'; import { getFirstSentryEnvelopeRequest } from './utils/helpers'; @@ -10,5 +8,5 @@ test('should add `pageload` transaction on load.', async ({ page }) => { expect(envelope.contexts?.trace.op).toBe('pageload'); expect(envelope.type).toBe('transaction'); - expect(envelope.transaction).toBe(useV2 ? 'root' : 'routes/index'); + expect(envelope.transaction).toBe('root'); }); diff --git a/packages/remix/test/integration/test/server/instrumentation-legacy/action.test.ts b/packages/remix/test/integration/test/server/instrumentation-legacy/action.test.ts index d9e91088cb8b..c502b801ed81 100644 --- a/packages/remix/test/integration/test/server/instrumentation-legacy/action.test.ts +++ b/packages/remix/test/integration/test/server/instrumentation-legacy/action.test.ts @@ -1,8 +1,6 @@ import { describe, it } from 'vitest'; import { RemixTestEnv, assertSentryEvent, assertSentryTransaction } from '../utils/helpers'; -const useV2 = process.env.REMIX_VERSION === '2'; - describe('Remix API Actions', () => { it('correctly instruments a parameterized Remix API action', async () => { const env = await RemixTestEnv.init(); @@ -15,10 +13,10 @@ describe('Remix API Actions', () => { const transaction = envelope[2]!; assertSentryTransaction(transaction, { - transaction: `routes/action-json-response${useV2 ? '.' : '/'}$id`, + transaction: `routes/action-json-response.$id`, spans: [ { - description: `routes/action-json-response${useV2 ? '.' : '/'}$id`, + description: `routes/action-json-response.$id`, op: 'function.remix.action', }, { @@ -26,11 +24,11 @@ describe('Remix API Actions', () => { op: 'function.remix.loader', }, { - description: `routes/action-json-response${useV2 ? '.' : '/'}$id`, + description: `routes/action-json-response.$id`, op: 'function.remix.loader', }, { - description: `routes/action-json-response${useV2 ? '.' : '/'}$id`, + description: `routes/action-json-response.$id`, op: 'function.remix.document_request', }, ], @@ -81,7 +79,7 @@ describe('Remix API Actions', () => { stacktrace: expect.any(Object), mechanism: { data: { - function: useV2 ? 'remix.server.handleError' : 'action', + function: 'remix.server.handleError', }, handled: false, type: 'instrument', @@ -107,7 +105,7 @@ describe('Remix API Actions', () => { const [event] = envelopes.filter(envelope => envelope[1]?.type === 'event'); assertSentryTransaction(transaction![2]!, { - transaction: `routes/action-json-response${useV2 ? '.' : '/'}$id`, + transaction: `routes/action-json-response.$id`, request: { method: 'POST', url, @@ -165,7 +163,7 @@ describe('Remix API Actions', () => { }, }, }, - transaction: `routes/action-json-response${useV2 ? '.' : '/'}$id`, + transaction: 'routes/action-json-response.$id', }); assertSentryTransaction(transaction_2![2]!, { @@ -179,7 +177,7 @@ describe('Remix API Actions', () => { }, }, }, - transaction: `routes/action-json-response${useV2 ? '.' : '/'}$id`, + transaction: 'routes/action-json-response.$id', }); assertSentryEvent(event![2]!, { @@ -192,7 +190,7 @@ describe('Remix API Actions', () => { stacktrace: expect.any(Object), mechanism: { data: { - function: useV2 ? 'remix.server.handleError' : 'loader', + function: 'remix.server.handleError', }, handled: false, type: 'instrument', @@ -228,7 +226,7 @@ describe('Remix API Actions', () => { }, }, }, - transaction: `routes/action-json-response${useV2 ? '.' : '/'}$id`, + transaction: 'routes/action-json-response.$id', }); assertSentryEvent(event![2]!, { @@ -277,7 +275,7 @@ describe('Remix API Actions', () => { }, }, }, - transaction: `routes/action-json-response${useV2 ? '.' : '/'}$id`, + transaction: 'routes/action-json-response.$id', }); assertSentryEvent(event![2]!, { @@ -326,7 +324,7 @@ describe('Remix API Actions', () => { }, }, }, - transaction: `routes/action-json-response${useV2 ? '.' : '/'}$id`, + transaction: 'routes/action-json-response.$id', }); assertSentryEvent(event![2]!, { @@ -375,7 +373,7 @@ describe('Remix API Actions', () => { }, }, }, - transaction: `routes/action-json-response${useV2 ? '.' : '/'}$id`, + transaction: 'routes/action-json-response.$id', }); assertSentryEvent(event![2]!, { @@ -424,7 +422,7 @@ describe('Remix API Actions', () => { }, }, }, - transaction: `routes/server-side-unexpected-errors${useV2 ? '.' : '/'}$id`, + transaction: 'routes/server-side-unexpected-errors.$id', }); assertSentryEvent(event![2]!, { @@ -437,7 +435,7 @@ describe('Remix API Actions', () => { stacktrace: expect.any(Object), mechanism: { data: { - function: useV2 ? 'remix.server.handleError' : 'action', + function: 'remix.server.handleError', }, handled: false, type: 'instrument', @@ -473,7 +471,7 @@ describe('Remix API Actions', () => { }, }, }, - transaction: `routes/server-side-unexpected-errors${useV2 ? '.' : '/'}$id`, + transaction: 'routes/server-side-unexpected-errors.$id', }); assertSentryEvent(event![2]!, { @@ -486,7 +484,7 @@ describe('Remix API Actions', () => { stacktrace: expect.any(Object), mechanism: { data: { - function: useV2 ? 'remix.server.handleError' : 'action', + function: 'remix.server.handleError', }, handled: false, type: 'instrument', diff --git a/packages/remix/test/integration/test/server/instrumentation-legacy/loader.test.ts b/packages/remix/test/integration/test/server/instrumentation-legacy/loader.test.ts index bf69b5e7e35b..79fb7bb270d3 100644 --- a/packages/remix/test/integration/test/server/instrumentation-legacy/loader.test.ts +++ b/packages/remix/test/integration/test/server/instrumentation-legacy/loader.test.ts @@ -2,8 +2,6 @@ import { Event } from '@sentry/core'; import { describe, expect, it } from 'vitest'; import { RemixTestEnv, assertSentryEvent, assertSentryTransaction } from '../utils/helpers'; -const useV2 = process.env.REMIX_VERSION === '2'; - describe('Remix API Loaders', () => { it('reports an error thrown from the loader', async () => { const env = await RemixTestEnv.init(); @@ -35,7 +33,7 @@ describe('Remix API Loaders', () => { stacktrace: expect.any(Object), mechanism: { data: { - function: useV2 ? 'remix.server.handleError' : 'loader', + function: 'remix.server.handleError', }, handled: false, type: 'instrument', @@ -96,7 +94,7 @@ describe('Remix API Loaders', () => { const transaction = envelope[2]!; assertSentryTransaction(transaction, { - transaction: `routes/loader-json-response${useV2 ? '.' : '/'}$id`, + transaction: 'routes/loader-json-response.$id', transaction_info: { source: 'route', }, @@ -106,11 +104,11 @@ describe('Remix API Loaders', () => { op: 'function.remix.loader', }, { - description: `routes/loader-json-response${useV2 ? '.' : '/'}$id`, + description: 'routes/loader-json-response.$id', op: 'function.remix.loader', }, { - description: `routes/loader-json-response${useV2 ? '.' : '/'}$id`, + description: 'routes/loader-json-response.$id', op: 'function.remix.document_request', }, ], @@ -141,7 +139,7 @@ describe('Remix API Loaders', () => { }, }, }, - transaction: `routes/loader-json-response${useV2 ? '.' : '/'}$id`, + transaction: 'routes/loader-json-response.$id', }); assertSentryTransaction(transaction_2![2]!, { @@ -155,7 +153,7 @@ describe('Remix API Loaders', () => { }, }, }, - transaction: `routes/loader-json-response${useV2 ? '.' : '/'}$id`, + transaction: 'routes/loader-json-response.$id', }); assertSentryEvent(event![2]!, { @@ -168,7 +166,7 @@ describe('Remix API Loaders', () => { stacktrace: expect.any(Object), mechanism: { data: { - function: useV2 ? 'remix.server.handleError' : 'loader', + function: 'remix.server.handleError', }, handled: false, type: 'instrument', @@ -236,39 +234,24 @@ describe('Remix API Loaders', () => { const transaction = envelope[2]!; assertSentryTransaction(transaction, { - transaction: useV2 ? 'routes/loader-defer-response.$id' : 'routes/loader-defer-response/$id', + transaction: 'routes/loader-defer-response.$id', transaction_info: { source: 'route', }, - spans: useV2 - ? [ - { - description: 'root', - op: 'function.remix.loader', - }, - { - description: 'routes/loader-defer-response.$id', - op: 'function.remix.loader', - }, - { - description: 'routes/loader-defer-response.$id', - op: 'function.remix.document_request', - }, - ] - : [ - { - description: 'root', - op: 'function.remix.loader', - }, - { - description: 'routes/loader-defer-response/$id', - op: 'function.remix.loader', - }, - { - description: 'routes/loader-defer-response/$id', - op: 'function.remix.document_request', - }, - ], + spans: [ + { + description: 'root', + op: 'function.remix.loader', + }, + { + description: 'routes/loader-defer-response.$id', + op: 'function.remix.loader', + }, + { + description: 'routes/loader-defer-response.$id', + op: 'function.remix.document_request', + }, + ], }); }); diff --git a/packages/remix/test/integration/test/server/instrumentation-legacy/ssr.test.ts b/packages/remix/test/integration/test/server/instrumentation-legacy/ssr.test.ts index 9fafe0a70056..c4ea2503e67f 100644 --- a/packages/remix/test/integration/test/server/instrumentation-legacy/ssr.test.ts +++ b/packages/remix/test/integration/test/server/instrumentation-legacy/ssr.test.ts @@ -1,8 +1,6 @@ import { describe, expect, it } from 'vitest'; import { RemixTestEnv, assertSentryEvent, assertSentryTransaction } from '../utils/helpers'; -const useV2 = process.env.REMIX_VERSION === '2'; - describe('Server Side Rendering', () => { it('correctly reports a server side rendering error', async () => { const env = await RemixTestEnv.init(); @@ -19,12 +17,10 @@ describe('Server Side Rendering', () => { }, }, }, - ...(useV2 && { - tags: { - // Testing that the wrapped `handleError` correctly adds tags - 'remix-test-tag': 'remix-test-value', - }, - }), + tags: { + // Testing that the wrapped `handleError` correctly adds tags + 'remix-test-tag': 'remix-test-value', + }, }); assertSentryEvent(event![2]!, { @@ -37,7 +33,7 @@ describe('Server Side Rendering', () => { stacktrace: expect.any(Object), mechanism: { data: { - function: useV2 ? 'remix.server.handleError' : 'documentRequest', + function: 'remix.server.handleError', }, handled: false, type: 'instrument', diff --git a/packages/remix/test/integration/test/server/instrumentation-otel/action.test.ts b/packages/remix/test/integration/test/server/instrumentation-otel/action.test.ts index f883c4bfeee5..e0a07ac82eae 100644 --- a/packages/remix/test/integration/test/server/instrumentation-otel/action.test.ts +++ b/packages/remix/test/integration/test/server/instrumentation-otel/action.test.ts @@ -1,8 +1,6 @@ import { describe, it } from 'vitest'; import { RemixTestEnv, assertSentryEvent, assertSentryTransaction } from '../utils/helpers'; -const useV2 = process.env.REMIX_VERSION === '2'; - describe('Remix API Actions', () => { it('correctly instruments a parameterized Remix API action', async () => { const env = await RemixTestEnv.init(); @@ -22,7 +20,7 @@ describe('Remix API Actions', () => { data: { 'code.function': 'action', 'sentry.op': 'action.remix', - 'match.route.id': `routes/action-json-response${useV2 ? '.' : '/'}$id`, + 'match.route.id': 'routes/action-json-response.$id', 'match.params.id': '123123', }, }, @@ -30,7 +28,7 @@ describe('Remix API Actions', () => { data: { 'code.function': 'loader', 'sentry.op': 'loader.remix', - 'match.route.id': `routes/action-json-response${useV2 ? '.' : '/'}$id`, + 'match.route.id': 'routes/action-json-response.$id', 'match.params.id': '123123', }, }, @@ -89,7 +87,7 @@ describe('Remix API Actions', () => { stacktrace: expect.any(Object), mechanism: { data: { - function: useV2 ? 'remix.server.handleError' : 'action', + function: 'remix.server.handleError', }, handled: false, type: 'instrument', @@ -197,7 +195,7 @@ describe('Remix API Actions', () => { stacktrace: expect.any(Object), mechanism: { data: { - function: useV2 ? 'remix.server.handleError' : 'loader', + function: 'remix.server.handleError', }, handled: false, type: 'instrument', @@ -432,7 +430,7 @@ describe('Remix API Actions', () => { stacktrace: expect.any(Object), mechanism: { data: { - function: useV2 ? 'remix.server.handleError' : 'action', + function: 'remix.server.handleError', }, handled: false, type: 'instrument', @@ -479,7 +477,7 @@ describe('Remix API Actions', () => { stacktrace: expect.any(Object), mechanism: { data: { - function: useV2 ? 'remix.server.handleError' : 'action', + function: 'remix.server.handleError', }, handled: false, type: 'instrument', diff --git a/packages/remix/test/integration/test/server/instrumentation-otel/loader.test.ts b/packages/remix/test/integration/test/server/instrumentation-otel/loader.test.ts index 93235b33d54d..baec26b3eb67 100644 --- a/packages/remix/test/integration/test/server/instrumentation-otel/loader.test.ts +++ b/packages/remix/test/integration/test/server/instrumentation-otel/loader.test.ts @@ -2,8 +2,6 @@ import { Event } from '@sentry/core'; import { describe, expect, it } from 'vitest'; import { RemixTestEnv, assertSentryEvent, assertSentryTransaction } from '../utils/helpers'; -const useV2 = process.env.REMIX_VERSION === '2'; - describe('Remix API Loaders', () => { it('reports an error thrown from the loader', async () => { const env = await RemixTestEnv.init(); @@ -34,7 +32,7 @@ describe('Remix API Loaders', () => { stacktrace: expect.any(Object), mechanism: { data: { - function: useV2 ? 'remix.server.handleError' : 'loader', + function: 'remix.server.handleError', }, handled: false, type: 'instrument', @@ -167,7 +165,7 @@ describe('Remix API Loaders', () => { stacktrace: expect.any(Object), mechanism: { data: { - function: useV2 ? 'remix.server.handleError' : 'loader', + function: 'remix.server.handleError', }, handled: false, type: 'instrument', @@ -244,7 +242,7 @@ describe('Remix API Loaders', () => { data: { 'code.function': 'loader', 'sentry.op': 'loader.remix', - 'match.route.id': `routes/loader-defer-response${useV2 ? '.' : '/'}$id`, + 'match.route.id': 'routes/loader-defer-response.$id', }, }, { diff --git a/packages/remix/test/integration/test/server/instrumentation-otel/ssr.test.ts b/packages/remix/test/integration/test/server/instrumentation-otel/ssr.test.ts index f3a5d7e4124f..1b2a97a99b55 100644 --- a/packages/remix/test/integration/test/server/instrumentation-otel/ssr.test.ts +++ b/packages/remix/test/integration/test/server/instrumentation-otel/ssr.test.ts @@ -1,8 +1,6 @@ import { describe, expect, it } from 'vitest'; import { RemixTestEnv, assertSentryEvent, assertSentryTransaction } from '../utils/helpers'; -const useV2 = process.env.REMIX_VERSION === '2'; - describe('Server Side Rendering', () => { it('correctly reports a server side rendering error', async () => { const env = await RemixTestEnv.init(); @@ -20,12 +18,10 @@ describe('Server Side Rendering', () => { }, }, }, - ...(useV2 && { - tags: { - // Testing that the wrapped `handleError` correctly adds tags - 'remix-test-tag': 'remix-test-value', - }, - }), + tags: { + // Testing that the wrapped `handleError` correctly adds tags + 'remix-test-tag': 'remix-test-value', + }, }); assertSentryEvent(event[2], { @@ -37,7 +33,7 @@ describe('Server Side Rendering', () => { stacktrace: expect.any(Object), mechanism: { data: { - function: useV2 ? 'remix.server.handleError' : 'documentRequest', + function: 'remix.server.handleError', }, handled: false, type: 'instrument', diff --git a/packages/remix/test/integration/tsconfig.json b/packages/remix/test/integration/tsconfig.json index f190b5da307f..1ab42867a9dc 100644 --- a/packages/remix/test/integration/tsconfig.json +++ b/packages/remix/test/integration/tsconfig.json @@ -13,7 +13,7 @@ "forceConsistentCasingInFileNames": true, "baseUrl": ".", "paths": { - "~/*": ["app_v1/*", "app_v2/*"] + "~/*": ["app_v2/*"] }, "noEmit": true } From e28a73a7acb08dd490224ab87010e822e49acb06 Mon Sep 17 00:00:00 2001 From: Charly Gomez Date: Thu, 16 Jan 2025 12:01:07 +0100 Subject: [PATCH 06/16] remove v1 e2e tests --- .../create-remix-app-legacy/.eslintrc.js | 4 - .../create-remix-app-legacy/.gitignore | 6 - .../create-remix-app-legacy/.npmrc | 2 - .../app/entry.client.tsx | 31 --- .../app/entry.server.tsx | 114 ---------- .../create-remix-app-legacy/app/root.tsx | 76 ------- .../app/routes/_index.tsx | 26 --- .../app/routes/client-error.tsx | 13 -- .../app/routes/navigate.tsx | 20 -- .../app/routes/user.$id.tsx | 3 - .../create-remix-app-legacy/globals.d.ts | 7 - .../create-remix-app-legacy/package.json | 47 ----- .../playwright.config.mjs | 7 - .../create-remix-app-legacy/remix.config.js | 17 -- .../start-event-proxy.mjs | 6 - .../tests/client-errors.test.ts | 29 --- .../tests/client-transactions.test.ts | 57 ----- .../tests/server-transactions.test.ts | 57 ----- .../create-remix-app-legacy/tsconfig.json | 22 -- .../upload-sourcemaps.sh | 3 - .../create-remix-app/.eslintrc.js | 4 - .../create-remix-app/.gitignore | 6 - .../test-applications/create-remix-app/.npmrc | 2 - .../create-remix-app/app/entry.client.tsx | 32 --- .../create-remix-app/app/entry.server.tsx | 106 ---------- .../create-remix-app/app/root.tsx | 76 ------- .../create-remix-app/app/routes/_index.tsx | 26 --- .../app/routes/client-error.tsx | 13 -- .../create-remix-app/app/routes/navigate.tsx | 20 -- .../create-remix-app/app/routes/user.$id.tsx | 16 -- .../create-remix-app/globals.d.ts | 7 - .../create-remix-app/instrument.server.cjs | 9 - .../create-remix-app/package.json | 47 ----- .../create-remix-app/playwright.config.mjs | 7 - .../create-remix-app/remix.config.js | 17 -- .../create-remix-app/start-event-proxy.mjs | 6 - .../tests/client-errors.test.ts | 29 --- .../create-remix-app/tests/client-inp.test.ts | 198 ------------------ .../tests/client-transactions.test.ts | 57 ----- .../tests/server-transactions.test.ts | 60 ------ .../create-remix-app/tsconfig.json | 22 -- .../create-remix-app/upload-sourcemaps.sh | 3 - 42 files changed, 1310 deletions(-) delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app-legacy/.eslintrc.js delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app-legacy/.gitignore delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app-legacy/.npmrc delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app-legacy/app/entry.client.tsx delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app-legacy/app/entry.server.tsx delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app-legacy/app/root.tsx delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app-legacy/app/routes/_index.tsx delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app-legacy/app/routes/client-error.tsx delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app-legacy/app/routes/navigate.tsx delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app-legacy/app/routes/user.$id.tsx delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app-legacy/globals.d.ts delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app-legacy/package.json delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app-legacy/playwright.config.mjs delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app-legacy/remix.config.js delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app-legacy/start-event-proxy.mjs delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app-legacy/tests/client-errors.test.ts delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app-legacy/tests/client-transactions.test.ts delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app-legacy/tests/server-transactions.test.ts delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app-legacy/tsconfig.json delete mode 100755 dev-packages/e2e-tests/test-applications/create-remix-app-legacy/upload-sourcemaps.sh delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app/.eslintrc.js delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app/.gitignore delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app/.npmrc delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app/app/entry.client.tsx delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app/app/entry.server.tsx delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app/app/root.tsx delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app/app/routes/_index.tsx delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app/app/routes/client-error.tsx delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app/app/routes/navigate.tsx delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app/app/routes/user.$id.tsx delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app/globals.d.ts delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app/instrument.server.cjs delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app/package.json delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app/playwright.config.mjs delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app/remix.config.js delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app/start-event-proxy.mjs delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app/tests/client-errors.test.ts delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app/tests/client-inp.test.ts delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app/tests/client-transactions.test.ts delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app/tests/server-transactions.test.ts delete mode 100644 dev-packages/e2e-tests/test-applications/create-remix-app/tsconfig.json delete mode 100755 dev-packages/e2e-tests/test-applications/create-remix-app/upload-sourcemaps.sh diff --git a/dev-packages/e2e-tests/test-applications/create-remix-app-legacy/.eslintrc.js b/dev-packages/e2e-tests/test-applications/create-remix-app-legacy/.eslintrc.js deleted file mode 100644 index f2faf1470fd8..000000000000 --- a/dev-packages/e2e-tests/test-applications/create-remix-app-legacy/.eslintrc.js +++ /dev/null @@ -1,4 +0,0 @@ -/** @type {import('eslint').Linter.Config} */ -module.exports = { - extends: ['@remix-run/eslint-config', '@remix-run/eslint-config/node'], -}; diff --git a/dev-packages/e2e-tests/test-applications/create-remix-app-legacy/.gitignore b/dev-packages/e2e-tests/test-applications/create-remix-app-legacy/.gitignore deleted file mode 100644 index 3f7bf98da3e1..000000000000 --- a/dev-packages/e2e-tests/test-applications/create-remix-app-legacy/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -node_modules - -/.cache -/build -/public/build -.env diff --git a/dev-packages/e2e-tests/test-applications/create-remix-app-legacy/.npmrc b/dev-packages/e2e-tests/test-applications/create-remix-app-legacy/.npmrc deleted file mode 100644 index 070f80f05092..000000000000 --- a/dev-packages/e2e-tests/test-applications/create-remix-app-legacy/.npmrc +++ /dev/null @@ -1,2 +0,0 @@ -@sentry:registry=http://127.0.0.1:4873 -@sentry-internal:registry=http://127.0.0.1:4873 diff --git a/dev-packages/e2e-tests/test-applications/create-remix-app-legacy/app/entry.client.tsx b/dev-packages/e2e-tests/test-applications/create-remix-app-legacy/app/entry.client.tsx deleted file mode 100644 index d0c95287e0c9..000000000000 --- a/dev-packages/e2e-tests/test-applications/create-remix-app-legacy/app/entry.client.tsx +++ /dev/null @@ -1,31 +0,0 @@ -/** - * By default, Remix will handle hydrating your app on the client for you. - * You are free to delete this file if you'd like to, but if you ever want it revealed again, you can run `npx remix reveal` ✨ - * For more information, see https://remix.run/file-conventions/entry.client - */ - -import { RemixBrowser, useLocation, useMatches } from '@remix-run/react'; -import * as Sentry from '@sentry/remix'; -import { StrictMode, startTransition, useEffect } from 'react'; -import { hydrateRoot } from 'react-dom/client'; - -Sentry.init({ - environment: 'qa', // dynamic sampling bias to keep transactions - dsn: window.ENV.SENTRY_DSN, - integrations: [Sentry.browserTracingIntegration({ useEffect, useMatches, useLocation }), Sentry.replayIntegration()], - // Performance Monitoring - tracesSampleRate: 1.0, // Capture 100% of the transactions, reduce in production! - // Session Replay - replaysSessionSampleRate: 0.1, // This sets the sample rate at 10%. You may want to change it to 100% while in development and then sample at a lower rate in production. - replaysOnErrorSampleRate: 1.0, // If you're not already sampling the entire session, change the sample rate to 100% when sampling sessions where errors occur. - tunnel: 'http://localhost:3031/', // proxy server -}); - -startTransition(() => { - hydrateRoot( - document, - - - , - ); -}); diff --git a/dev-packages/e2e-tests/test-applications/create-remix-app-legacy/app/entry.server.tsx b/dev-packages/e2e-tests/test-applications/create-remix-app-legacy/app/entry.server.tsx deleted file mode 100644 index b0f1c5d19f09..000000000000 --- a/dev-packages/e2e-tests/test-applications/create-remix-app-legacy/app/entry.server.tsx +++ /dev/null @@ -1,114 +0,0 @@ -import * as Sentry from '@sentry/remix'; - -Sentry.init({ - tracesSampleRate: 1.0, // Capture 100% of the transactions, reduce in production! - environment: 'qa', // dynamic sampling bias to keep transactions - dsn: process.env.E2E_TEST_DSN, - tunnel: 'http://localhost:3031/', // proxy server -}); - -/** - * By default, Remix will handle generating the HTTP Response for you. - * You are free to delete this file if you'd like to, but if you ever want it revealed again, you can run `npx remix reveal` ✨ - * For more information, see https://remix.run/file-conventions/entry.server - */ - -import { PassThrough } from 'node:stream'; - -import type { AppLoadContext, EntryContext } from '@remix-run/node'; -import { Response } from '@remix-run/node'; -import { RemixServer } from '@remix-run/react'; -import isbot from 'isbot'; -import { renderToPipeableStream } from 'react-dom/server'; - -const ABORT_DELAY = 5_000; - -export const handleError = Sentry.wrapRemixHandleError; - -export default function handleRequest( - request: Request, - responseStatusCode: number, - responseHeaders: Headers, - remixContext: EntryContext, - loadContext: AppLoadContext, -) { - return isbot(request.headers.get('user-agent')) - ? handleBotRequest(request, responseStatusCode, responseHeaders, remixContext) - : handleBrowserRequest(request, responseStatusCode, responseHeaders, remixContext); -} - -function handleBotRequest( - request: Request, - responseStatusCode: number, - responseHeaders: Headers, - remixContext: EntryContext, -) { - return new Promise((resolve, reject) => { - const { pipe, abort } = renderToPipeableStream( - , - { - onAllReady() { - const body = new PassThrough(); - - responseHeaders.set('Content-Type', 'text/html'); - - resolve( - new Response(body, { - headers: responseHeaders, - status: responseStatusCode, - }), - ); - - pipe(body); - }, - onShellError(error: unknown) { - reject(error); - }, - onError(error: unknown) { - responseStatusCode = 500; - console.error(error); - }, - }, - ); - - setTimeout(abort, ABORT_DELAY); - }); -} - -function handleBrowserRequest( - request: Request, - responseStatusCode: number, - responseHeaders: Headers, - remixContext: EntryContext, -) { - return new Promise((resolve, reject) => { - const { pipe, abort } = renderToPipeableStream( - , - { - onShellReady() { - const body = new PassThrough(); - - responseHeaders.set('Content-Type', 'text/html'); - - resolve( - new Response(body, { - headers: responseHeaders, - status: responseStatusCode, - }), - ); - - pipe(body); - }, - onShellError(error: unknown) { - reject(error); - }, - onError(error: unknown) { - console.error(error); - responseStatusCode = 500; - }, - }, - ); - - setTimeout(abort, ABORT_DELAY); - }); -} diff --git a/dev-packages/e2e-tests/test-applications/create-remix-app-legacy/app/root.tsx b/dev-packages/e2e-tests/test-applications/create-remix-app-legacy/app/root.tsx deleted file mode 100644 index e99991f5994d..000000000000 --- a/dev-packages/e2e-tests/test-applications/create-remix-app-legacy/app/root.tsx +++ /dev/null @@ -1,76 +0,0 @@ -import { cssBundleHref } from '@remix-run/css-bundle'; -import { LinksFunction, MetaFunction, json } from '@remix-run/node'; -import { - Links, - LiveReload, - Meta, - Outlet, - Scripts, - ScrollRestoration, - useLoaderData, - useRouteError, -} from '@remix-run/react'; -import { captureRemixErrorBoundaryError, withSentry } from '@sentry/remix'; - -export const links: LinksFunction = () => [...(cssBundleHref ? [{ rel: 'stylesheet', href: cssBundleHref }] : [])]; - -export const loader = () => { - return json({ - ENV: { - SENTRY_DSN: process.env.E2E_TEST_DSN, - }, - }); -}; - -export const meta: MetaFunction = ({ data }) => { - return [ - { - name: 'sentry-trace', - content: data.sentryTrace, - }, - { - name: 'baggage', - content: data.sentryBaggage, - }, - ]; -}; - -export function ErrorBoundary() { - const error = useRouteError(); - const eventId = captureRemixErrorBoundaryError(error); - - return ( -

- ErrorBoundary Error - {eventId} -
- ); -} - -function App() { - const { ENV } = useLoaderData(); - - return ( - - - - -