@@ -69,8 +69,41 @@ interface DataFunction {
69
69
( args : DataFunctionArgs ) : Promise < Response > | Response | Promise < AppData > | AppData ;
70
70
}
71
71
72
+ // Taken from Remix Implementation
73
+ // https://github.com/remix-run/remix/blob/7688da5c75190a2e29496c78721456d6e12e3abe/packages/remix-server-runtime/responses.ts#L54-L62
74
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
75
+ function isResponse ( value : any ) : value is Response {
76
+ return (
77
+ value != null &&
78
+ /* eslint-disable @typescript-eslint/no-unsafe-member-access */
79
+ typeof value . status === 'number' &&
80
+ typeof value . statusText === 'string' &&
81
+ typeof value . headers === 'object' &&
82
+ typeof value . body !== 'undefined'
83
+ /* eslint-enable @typescript-eslint/no-unsafe-member-access */
84
+ ) ;
85
+ }
86
+
87
+ // Taken from Remix Implementation
88
+ // https://github.com/remix-run/remix/blob/7688da5c75190a2e29496c78721456d6e12e3abe/packages/remix-server-runtime/data.ts#L131-L145
89
+ function extractData ( response : Response ) : Promise < unknown > {
90
+ const contentType = response . headers . get ( 'Content-Type' ) ;
91
+
92
+ if ( contentType && / \b a p p l i c a t i o n \/ j s o n \b / . test ( contentType ) ) {
93
+ return response . json ( ) ;
94
+ }
95
+
96
+ return response . text ( ) ;
97
+ }
98
+
72
99
function captureRemixServerException ( err : Error , name : string ) : void {
73
- captureException ( err , scope => {
100
+ // Skip capturing if the thrown error is an OK Response
101
+ // https://remix.run/docs/en/v1/api/conventions#throwing-responses-in-loaders
102
+ if ( isResponse ( err ) && err . status < 400 ) {
103
+ return ;
104
+ }
105
+
106
+ captureException ( isResponse ( err ) ? extractData ( err ) : err , scope => {
74
107
scope . addEventProcessor ( event => {
75
108
addExceptionMechanism ( event , {
76
109
type : 'instrument' ,
0 commit comments