@@ -325,7 +325,12 @@ Raven.prototype = {
325325 */
326326 captureException : function ( ex , options ) {
327327 // If not an Error is passed through, recall as a message instead
328- if ( ! isError ( ex ) ) return this . captureMessage ( ex , options ) ;
328+ if ( ! isError ( ex ) ) {
329+ return this . captureMessage ( ex , objectMerge ( {
330+ trimHeadFrames : 1 ,
331+ stacktrace : true // if we fall back to captureMessage, default to attempting a new trace
332+ } , options ) ) ;
333+ }
329334
330335 // Store the raw exception object for potential debugging and introspection
331336 this . _lastCapturedException = ex ;
@@ -362,12 +367,41 @@ Raven.prototype = {
362367 return ;
363368 }
364369
370+ var data = objectMerge ( {
371+ message : msg + '' // Make sure it's actually a string
372+ } , options ) ;
373+
374+ if ( options && options . stacktrace ) {
375+ var ex ;
376+ // create a stack trace from this point; just trim
377+ // off extra frames so they don't include this function call (or
378+ // earlier Raven.js library fn calls)
379+ try {
380+ throw new Error ( msg ) ;
381+ } catch ( ex1 ) {
382+ ex = ex1 ;
383+ }
384+
385+ // null exception name so `Error` isn't prefixed to msg
386+ ex . name = null ;
387+
388+ options = objectMerge ( {
389+ // fingerprint on msg, not stack trace (legacy behavior, could be
390+ // revisited)
391+ fingerprint : msg ,
392+ trimHeadFrames : ( options . trimHeadFrames || 0 ) + 1
393+ } , options ) ;
394+
395+ var stack = TraceKit . computeStackTrace ( ex ) ;
396+ var frames = this . _prepareFrames ( stack , options ) ;
397+ data . stacktrace = {
398+ // Sentry expects frames oldest to newest
399+ frames : frames . reverse ( )
400+ }
401+ }
402+
365403 // Fire away!
366- this . _send (
367- objectMerge ( {
368- message : msg + '' // Make sure it's actually a string
369- } , options )
370- ) ;
404+ this . _send ( data ) ;
371405
372406 return this ;
373407 } ,
@@ -1066,17 +1100,7 @@ Raven.prototype = {
10661100 } ,
10671101
10681102 _handleStackInfo : function ( stackInfo , options ) {
1069- var self = this ;
1070- var frames = [ ] ;
1071-
1072- if ( stackInfo . stack && stackInfo . stack . length ) {
1073- each ( stackInfo . stack , function ( i , stack ) {
1074- var frame = self . _normalizeFrame ( stack ) ;
1075- if ( frame ) {
1076- frames . push ( frame ) ;
1077- }
1078- } ) ;
1079- }
1103+ var frames = this . _prepareFrames ( stackInfo , options ) ;
10801104
10811105 this . _triggerEvent ( 'handle' , {
10821106 stackInfo : stackInfo ,
@@ -1088,11 +1112,36 @@ Raven.prototype = {
10881112 stackInfo . message ,
10891113 stackInfo . url ,
10901114 stackInfo . lineno ,
1091- frames . slice ( 0 , this . _globalOptions . stackTraceLimit ) ,
1115+ frames ,
10921116 options
10931117 ) ;
10941118 } ,
10951119
1120+ _prepareFrames : function ( stackInfo , options ) {
1121+ var self = this ;
1122+ var frames = [ ] ;
1123+ if ( stackInfo . stack && stackInfo . stack . length ) {
1124+ each ( stackInfo . stack , function ( i , stack ) {
1125+ var frame = self . _normalizeFrame ( stack ) ;
1126+ if ( frame ) {
1127+ frames . push ( frame ) ;
1128+ }
1129+ } ) ;
1130+
1131+ // e.g. frames captured via captureMessage throw
1132+ if ( options && options . trimHeadFrames ) {
1133+ for ( var j = 0 ; j < options . trimHeadFrames && j < frames . length ; j ++ ) {
1134+ frames [ j ] . in_app = false ;
1135+ }
1136+ // ... delete to prevent from appearing in outbound payload
1137+ delete options . trimHeadFrames ;
1138+ }
1139+ }
1140+ frames = frames . slice ( 0 , this . _globalOptions . stackTraceLimit ) ;
1141+ return frames ;
1142+ } ,
1143+
1144+
10961145 _normalizeFrame : function ( frame ) {
10971146 if ( ! frame . url ) return ;
10981147
@@ -1118,7 +1167,6 @@ Raven.prototype = {
11181167
11191168 _processException : function ( type , message , fileurl , lineno , frames , options ) {
11201169 var stacktrace ;
1121-
11221170 if ( ! ! this . _globalOptions . ignoreErrors . test && this . _globalOptions . ignoreErrors . test ( message ) ) return ;
11231171
11241172 message += '' ;
0 commit comments