@@ -22,14 +22,29 @@ export function instrumentHandleError(
22
22
) : boolean {
23
23
const originalEntryServerModAST = originalEntryServerMod . $ast as Program ;
24
24
25
- const handleErrorFunction = originalEntryServerModAST . body . find (
26
- ( node ) =>
27
- node . type === 'ExportNamedDeclaration' &&
28
- node . declaration ?. type === 'FunctionDeclaration' &&
29
- node . declaration . id ?. name === 'handleError' ,
25
+ const handleErrorFunctionExport = originalEntryServerModAST . body . find (
26
+ ( node ) => {
27
+ return (
28
+ node . type === 'ExportNamedDeclaration' &&
29
+ node . declaration ?. type === 'FunctionDeclaration' &&
30
+ node . declaration . id ?. name === 'handleError'
31
+ ) ;
32
+ } ,
30
33
) ;
31
34
32
- if ( ! handleErrorFunction ) {
35
+ const handleErrorFunctionVariableDeclarationExport =
36
+ originalEntryServerModAST . body . find (
37
+ ( node ) =>
38
+ node . type === 'ExportNamedDeclaration' &&
39
+ node . declaration ?. type === 'VariableDeclaration' &&
40
+ // @ts -expect-error - id should always have a name in this case
41
+ node . declaration . declarations [ 0 ] . id . name === 'handleError' ,
42
+ ) ;
43
+
44
+ if (
45
+ ! handleErrorFunctionExport &&
46
+ ! handleErrorFunctionVariableDeclarationExport
47
+ ) {
33
48
clack . log . warn (
34
49
`Could not find function ${ chalk . cyan ( 'handleError' ) } in ${ chalk . cyan (
35
50
serverEntryFilename ,
@@ -48,50 +63,55 @@ export function instrumentHandleError(
48
63
recast . types . builders . exportNamedDeclaration ( implementation ) ,
49
64
) ;
50
65
} else if (
51
- hasSentryContent (
52
- generateCode ( handleErrorFunction ) . code ,
53
- originalEntryServerMod . $code ,
54
- 'captureRemixServerException' ,
55
- )
66
+ ( handleErrorFunctionExport &&
67
+ [ 'wrapHandleErrorWithSentry' , 'sentryHandleError' ] . some ( ( util ) =>
68
+ hasSentryContent (
69
+ generateCode ( handleErrorFunctionExport ) . code ,
70
+ originalEntryServerMod . $code ,
71
+ util ,
72
+ ) ,
73
+ ) ) ||
74
+ ( handleErrorFunctionVariableDeclarationExport &&
75
+ [ 'wrapHandleErrorWithSentry' , 'sentryHandleError' ] . some ( ( util ) =>
76
+ hasSentryContent (
77
+ generateCode ( handleErrorFunctionVariableDeclarationExport ) . code ,
78
+ originalEntryServerMod . $code ,
79
+ util ,
80
+ ) ,
81
+ ) )
56
82
) {
57
83
return false ;
58
- } else {
84
+ } else if ( handleErrorFunctionExport ) {
59
85
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
60
86
const implementation = recast . parse ( HANDLE_ERROR_TEMPLATE_V2 ) . program
61
87
. body [ 0 ] ;
62
88
63
- // @ts -expect-error - string works here because the AST is proxified by magicast
89
+ // If the current handleError function has a body, we need to merge the new implementation with the existing one
64
90
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
65
- handleErrorFunction . declaration . body . body . unshift (
91
+ implementation . declarations [ 0 ] . init . arguments [ 0 ] . body . body . unshift (
92
+ // @ts -expect-error - declaration works here because the AST is proxified by magicast
66
93
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
67
- recast . parse ( HANDLE_ERROR_TEMPLATE_V2 ) . program . body [ 0 ] . body . body [ 0 ] ,
94
+ ... handleErrorFunctionExport . declaration . body . body ,
68
95
) ;
69
96
70
- // First parameter is the error
71
- //
72
- // @ts -expect-error - string works here because the AST is proxified by magicast
97
+ // @ts -expect-error - declaration works here because the AST is proxified by magicast
98
+ handleErrorFunctionExport . declaration = implementation ;
99
+ } else if ( handleErrorFunctionVariableDeclarationExport ) {
73
100
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
74
- handleErrorFunction . declaration . params [ 0 ] = implementation . params [ 0 ] ;
101
+ const implementation = recast . parse ( HANDLE_ERROR_TEMPLATE_V2 ) . program
102
+ . body [ 0 ] ;
75
103
76
- // Second parameter is the request inside an object
77
- // Merging the object properties to make sure it includes request
78
- //
79
- // @ts -expect-error - string works here because the AST is proxified by magicast
80
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
81
- if ( handleErrorFunction . declaration . params ?. [ 1 ] ?. properties ) {
82
- // @ts -expect-error - string works here because the AST is proxified by magicast
83
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
84
- handleErrorFunction . declaration . params [ 1 ] . properties . push (
85
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
86
- implementation . params [ 1 ] . properties [ 0 ] ,
87
- ) ;
88
- } else {
89
- // Create second parameter if it doesn't exist
90
- //
91
- // @ts -expect-error - string works here because the AST is proxified by magicast
104
+ // If the current handleError function has a body, we need to merge the new implementation with the existing one
105
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
106
+ implementation . declarations [ 0 ] . init . arguments [ 0 ] . body . body . unshift (
107
+ // @ts -expect-error - declaration works here because the AST is proxified by magicast
92
108
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
93
- handleErrorFunction . declaration . params [ 1 ] = implementation . params [ 1 ] ;
94
- }
109
+ ...handleErrorFunctionVariableDeclarationExport . declaration
110
+ . declarations [ 0 ] . init . body . body ,
111
+ ) ;
112
+
113
+ // @ts -expect-error - declaration works here because the AST is proxified by magicast
114
+ handleErrorFunctionVariableDeclarationExport . declaration = implementation ;
95
115
}
96
116
97
117
return true ;
0 commit comments