| 
3 | 3 |  * largely modified and is now maintained as part of Sentry JS SDK.  | 
4 | 4 |  */  | 
5 | 5 | 
 
  | 
6 |  | -/* eslint-disable @typescript-eslint/no-unsafe-member-access */  | 
 | 6 | +/* eslint-disable @typescript-eslint/no-unsafe-member-access, max-lines */  | 
7 | 7 | 
 
  | 
8 | 8 | /**  | 
9 | 9 |  * An object representing a single stack frame.  | 
@@ -124,16 +124,10 @@ function computeStackTraceFromStackProp(ex: any): StackTrace | null {  | 
124 | 124 |       // Arpad: Working with the regexp above is super painful. it is quite a hack, but just stripping the `address at `  | 
125 | 125 |       // prefix here seems like the quickest solution for now.  | 
126 | 126 |       let url = parts[2] && parts[2].indexOf('address at ') === 0 ? parts[2].substr('address at '.length) : parts[2];  | 
127 |  | - | 
128 | 127 |       // Kamil: One more hack won't hurt us right? Understanding and adding more rules on top of these regexps right now  | 
129 | 128 |       // would be way too time consuming. (TODO: Rewrite whole RegExp to be more readable)  | 
130 | 129 |       let func = parts[1] || UNKNOWN_FUNCTION;  | 
131 |  | -      const isSafariExtension = func.indexOf('safari-extension') !== -1;  | 
132 |  | -      const isSafariWebExtension = func.indexOf('safari-web-extension') !== -1;  | 
133 |  | -      if (isSafariExtension || isSafariWebExtension) {  | 
134 |  | -        func = func.indexOf('@') !== -1 ? func.split('@')[0] : UNKNOWN_FUNCTION;  | 
135 |  | -        url = isSafariExtension ? `safari-extension:${url}` : `safari-web-extension:${url}`;  | 
136 |  | -      }  | 
 | 130 | +      [func, url] = extractSafariExtensionDetails(func, url);  | 
137 | 131 | 
 
  | 
138 | 132 |       element = {  | 
139 | 133 |         url,  | 
@@ -165,9 +159,14 @@ function computeStackTraceFromStackProp(ex: any): StackTrace | null {  | 
165 | 159 |         // NOTE: this hack doesn't work if top-most frame is eval  | 
166 | 160 |         stack[0].column = (ex.columnNumber as number) + 1;  | 
167 | 161 |       }  | 
 | 162 | + | 
 | 163 | +      let url = parts[3];  | 
 | 164 | +      let func = parts[1] || UNKNOWN_FUNCTION;  | 
 | 165 | +      [func, url] = extractSafariExtensionDetails(func, url);  | 
 | 166 | + | 
168 | 167 |       element = {  | 
169 |  | -        url: parts[3],  | 
170 |  | -        func: parts[1] || UNKNOWN_FUNCTION,  | 
 | 168 | +        url,  | 
 | 169 | +        func,  | 
171 | 170 |         args: parts[2] ? parts[2].split(',') : [],  | 
172 | 171 |         line: parts[4] ? +parts[4] : null,  | 
173 | 172 |         column: parts[5] ? +parts[5] : null,  | 
@@ -249,6 +248,38 @@ function computeStackTraceFromStacktraceProp(ex: any): StackTrace | null {  | 
249 | 248 |   };  | 
250 | 249 | }  | 
251 | 250 | 
 
  | 
 | 251 | +/**  | 
 | 252 | + * Safari web extensions, starting version unknown, can produce "frames-only" stacktraces.  | 
 | 253 | + * What it means, is that instead of format like:  | 
 | 254 | + *  | 
 | 255 | + * Error: wat  | 
 | 256 | + *   at function@url:row:col  | 
 | 257 | + *   at function@url:row:col  | 
 | 258 | + *   at function@url:row:col  | 
 | 259 | + *  | 
 | 260 | + * it produces something like:  | 
 | 261 | + *  | 
 | 262 | + *   function@url:row:col  | 
 | 263 | + *   function@url:row:col  | 
 | 264 | + *   function@url:row:col  | 
 | 265 | + *  | 
 | 266 | + * Because of that, it won't be captured by `chrome` RegExp and will fall into `Gecko` branch.  | 
 | 267 | + * This function is extracted so that we can use it in both places without duplicating the logic.  | 
 | 268 | + * Unfortunatelly "just" changing RegExp is too complicated now and making it pass all tests  | 
 | 269 | + * and fix this case seems like an impossible, or at least way too time-consuming task.  | 
 | 270 | + */  | 
 | 271 | +const extractSafariExtensionDetails = (func: string, url: string): [string, string] => {  | 
 | 272 | +  const isSafariExtension = func.indexOf('safari-extension') !== -1;  | 
 | 273 | +  const isSafariWebExtension = func.indexOf('safari-web-extension') !== -1;  | 
 | 274 | + | 
 | 275 | +  return isSafariExtension || isSafariWebExtension  | 
 | 276 | +    ? [  | 
 | 277 | +        func.indexOf('@') !== -1 ? func.split('@')[0] : UNKNOWN_FUNCTION,  | 
 | 278 | +        isSafariExtension ? `safari-extension:${url}` : `safari-web-extension:${url}`,  | 
 | 279 | +      ]  | 
 | 280 | +    : [func, url];  | 
 | 281 | +};  | 
 | 282 | + | 
252 | 283 | /** Remove N number of frames from the stack */  | 
253 | 284 | function popFrames(stacktrace: StackTrace, popSize: number): StackTrace {  | 
254 | 285 |   try {  | 
 | 
0 commit comments