@@ -2,30 +2,84 @@ import { rewriteFramesIntegration } from '@sentry/browser';
2
2
import { defineIntegration } from '@sentry/core' ;
3
3
4
4
export 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
+ } ) => {
6
16
const rewriteFramesInstance = rewriteFramesIntegration ( {
7
17
// Turn `<origin>/<path>/_next/static/...` into `app:///_next/static/...`
8
18
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
+ }
14
53
}
15
54
16
55
// 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.
17
56
// 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
+ }
21
74
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
+ }
29
83
}
30
84
31
85
return frame ;
0 commit comments