@@ -2,30 +2,84 @@ import { rewriteFramesIntegration } from '@sentry/browser';
22import { defineIntegration } from '@sentry/core' ;
33
44export const nextjsClientStackFrameNormalizationIntegration = defineIntegration (
5- ( { assetPrefixPath } : { assetPrefixPath : string } ) => {
5+ ( {
6+ assetPrefix,
7+ basePath,
8+ rewriteFramesAssetPrefixPath,
9+ experimentalThirdPartyOriginStackFrames,
10+ } : {
11+ assetPrefix ?: string ;
12+ basePath ?: string ;
13+ rewriteFramesAssetPrefixPath : string ;
14+ experimentalThirdPartyOriginStackFrames : boolean ;
15+ } ) => {
616 const rewriteFramesInstance = rewriteFramesIntegration ( {
717 // Turn `<origin>/<path>/_next/static/...` into `app:///_next/static/...`
818 iteratee : frame => {
9- try {
10- const { origin } = new URL ( frame . filename as string ) ;
11- frame . filename = frame . filename ?. replace ( origin , 'app://' ) . replace ( assetPrefixPath , '' ) ;
12- } catch ( err ) {
13- // Filename wasn't a properly formed URL, so there's nothing we can do
19+ if ( experimentalThirdPartyOriginStackFrames ) {
20+ // Not sure why but access to global WINDOW from @sentry /Browser causes hideous ci errors
21+ // eslint-disable-next-line no-restricted-globals
22+ const windowOrigin = typeof window !== 'undefined' && window . location ? window . location . origin : '' ;
23+ // A filename starting with the local origin and not ending with JS is most likely JS in HTML which we do not want to rewrite
24+ if ( frame . filename ?. startsWith ( windowOrigin ) && ! frame . filename . endsWith ( '.js' ) ) {
25+ return frame ;
26+ }
27+
28+ if ( assetPrefix ) {
29+ // If the user defined an asset prefix, we need to strip it so that we can match it with uploaded sourcemaps.
30+ // assetPrefix always takes priority over basePath.
31+ if ( frame . filename ?. startsWith ( assetPrefix ) ) {
32+ frame . filename = frame . filename . replace ( assetPrefix , 'app://' ) ;
33+ }
34+ } else if ( basePath ) {
35+ // If the user defined a base path, we need to strip it to match with uploaded sourcemaps.
36+ // We should only do this for same-origin filenames though, so that third party assets are not rewritten.
37+ try {
38+ const { origin : frameOrigin } = new URL ( frame . filename as string ) ;
39+ if ( frameOrigin === windowOrigin ) {
40+ frame . filename = frame . filename ?. replace ( frameOrigin , 'app://' ) . replace ( basePath , '' ) ;
41+ }
42+ } catch ( err ) {
43+ // Filename wasn't a properly formed URL, so there's nothing we can do
44+ }
45+ }
46+ } else {
47+ try {
48+ const { origin } = new URL ( frame . filename as string ) ;
49+ frame . filename = frame . filename ?. replace ( origin , 'app://' ) . replace ( rewriteFramesAssetPrefixPath , '' ) ;
50+ } catch ( err ) {
51+ // Filename wasn't a properly formed URL, so there's nothing we can do
52+ }
1453 }
1554
1655 // We need to URI-decode the filename because Next.js has wildcard routes like "/users/[id].js" which show up as "/users/%5id%5.js" in Error stacktraces.
1756 // The corresponding sources that Next.js generates have proper brackets so we also need proper brackets in the frame so that source map resolving works.
18- if ( frame . filename ?. startsWith ( 'app:///_next' ) ) {
19- frame . filename = decodeURI ( frame . filename ) ;
20- }
57+ if ( experimentalThirdPartyOriginStackFrames ) {
58+ if ( frame . filename ?. includes ( '/_next' ) ) {
59+ frame . filename = decodeURI ( frame . filename ) ;
60+ }
61+
62+ if (
63+ frame . filename ?. match (
64+ / \/ _ n e x t \/ s t a t i c \/ c h u n k s \/ ( m a i n - | m a i n - a p p - | p o l y f i l l s - | w e b p a c k - | f r a m e w o r k - | f r a m e w o r k \. ) [ 0 - 9 a - f ] + \. j s $ / ,
65+ )
66+ ) {
67+ // We don't care about these frames. It's Next.js internal code.
68+ frame . in_app = false ;
69+ }
70+ } else {
71+ if ( frame . filename ?. startsWith ( 'app:///_next' ) ) {
72+ frame . filename = decodeURI ( frame . filename ) ;
73+ }
2174
22- if (
23- frame . filename ?. match (
24- / ^ a p p : \/ \/ \/ _ n e x t \/ s t a t i c \/ c h u n k s \/ ( m a i n - | m a i n - a p p - | p o l y f i l l s - | w e b p a c k - | f r a m e w o r k - | f r a m e w o r k \. ) [ 0 - 9 a - f ] + \. j s $ / ,
25- )
26- ) {
27- // We don't care about these frames. It's Next.js internal code.
28- frame . in_app = false ;
75+ if (
76+ frame . filename ?. match (
77+ / ^ a p p : \/ \/ \/ _ n e x t \/ s t a t i c \/ c h u n k s \/ ( m a i n - | m a i n - a p p - | p o l y f i l l s - | w e b p a c k - | f r a m e w o r k - | f r a m e w o r k \. ) [ 0 - 9 a - f ] + \. j s $ / ,
78+ )
79+ ) {
80+ // We don't care about these frames. It's Next.js internal code.
81+ frame . in_app = false ;
82+ }
2983 }
3084
3185 return frame ;
0 commit comments