@@ -257,7 +257,9 @@ Raven.prototype = {
257
257
return func . apply ( this , args ) ;
258
258
} catch ( e ) {
259
259
self . _ignoreNextOnError ( ) ;
260
- self . captureException ( e , options , 1 ) ;
260
+ self . captureException ( e , objectMerge ( {
261
+ trimTailFrames : 1
262
+ } , options ) ) ;
261
263
throw e ;
262
264
}
263
265
}
@@ -302,11 +304,14 @@ Raven.prototype = {
302
304
* @param {object } options A specific set of options for this error [optional]
303
305
* @return {Raven }
304
306
*/
305
- captureException : function ( ex , options , skipframes ) {
306
- skipframes = skipframes || 0 ;
307
-
307
+ captureException : function ( ex , options ) {
308
308
// If not an Error is passed through, recall as a message instead
309
- if ( ! isError ( ex ) ) return this . captureMessage ( ex , options , skipframes + 1 ) ;
309
+ if ( ! isError ( ex ) ) {
310
+ return this . captureMessage ( ex , objectMerge ( {
311
+ trimHeadFrames : 1 ,
312
+ stacktrace : true // if we fall back to captureMessage, default to attempting a new trace
313
+ } , options ) ) ;
314
+ }
310
315
311
316
// Store the raw exception object for potential debugging and introspection
312
317
this . _lastCapturedException = ex ;
@@ -318,7 +323,7 @@ Raven.prototype = {
318
323
// report on.
319
324
try {
320
325
var stack = TraceKit . computeStackTrace ( ex ) ;
321
- this . _handleStackInfo ( stack , options , skipframes ) ;
326
+ this . _handleStackInfo ( stack , options ) ;
322
327
} catch ( ex1 ) {
323
328
if ( ex !== ex1 ) {
324
329
throw ex1 ;
@@ -335,7 +340,36 @@ Raven.prototype = {
335
340
* @param {object } options A specific set of options for this message [optional]
336
341
* @return {Raven }
337
342
*/
338
- captureMessage : function ( msg , options , skipframes ) {
343
+ captureMessage : function ( msg , options ) {
344
+ if ( options . stacktrace ) {
345
+ var ex ;
346
+ // create a stack trace from this point; just trim
347
+ // off extra frames so they don't include this function call (or
348
+ // earlier Raven.js library fn calls)
349
+ try {
350
+ throw new Error ( msg ) ;
351
+ } catch ( ex1 ) {
352
+ ex = ex1 ;
353
+ }
354
+
355
+ // null exception name so `Error` isn't prefixed to msg
356
+ ex . name = null ;
357
+
358
+ options = objectMerge ( {
359
+ // fingerprint on msg, not stack trace
360
+ // NOTE: need also to do this because stack could include Raven.wrap,
361
+ // which may create inconsistent traces if only using window.onerror
362
+ fingerprint : msg ,
363
+ trimTailFrames : ( options . trimHeadFrames || 0 ) + 1
364
+ } , options ) ;
365
+
366
+ // infinite loop if ex *somehow* returns false for isError
367
+ // is that possible when it is result of try/catch?
368
+ this . captureException ( ex , options ) ;
369
+
370
+ return this ;
371
+ }
372
+
339
373
// config() automagically converts ignoreErrors from a list to a RegExp so we need to test for an
340
374
// early call; we'll error on the side of logging anything called before configuration since it's
341
375
// probably something you should see:
@@ -1012,7 +1046,7 @@ Raven.prototype = {
1012
1046
}
1013
1047
} ,
1014
1048
1015
- _handleStackInfo : function ( stackInfo , options , skipframes ) {
1049
+ _handleStackInfo : function ( stackInfo , options ) {
1016
1050
var self = this ;
1017
1051
var frames = [ ] ;
1018
1052
@@ -1024,8 +1058,13 @@ Raven.prototype = {
1024
1058
}
1025
1059
} ) ;
1026
1060
1027
- if ( skipframes ) {
1028
- frames = frames . slice ( 0 , skipframes ) ;
1061
+ // e.g. frames captured via captureMessage throw
1062
+ if ( options . trimHeadFrames ) {
1063
+ frames = frames . slice ( options . trimHeadFrames ) ;
1064
+ }
1065
+ // e.g. try/catch (wrapper) frames
1066
+ if ( options . trimTailFrames ) {
1067
+ frames = frames . slice ( 0 , options . trimTailFrames ) ;
1029
1068
}
1030
1069
}
1031
1070
0 commit comments