@@ -572,10 +572,9 @@ function createItem(args, logger, notifier, requestKeys, lambdaContext) {
572
572
diagnostic : diagnostic ,
573
573
uuid : uuid4 ( )
574
574
} ;
575
- if ( custom && custom . level !== undefined ) {
576
- item . level = custom . level ;
577
- delete custom . level ;
578
- }
575
+
576
+ setCustomItemKeys ( item , custom ) ;
577
+
579
578
if ( requestKeys && request ) {
580
579
item . request = request ;
581
580
}
@@ -586,6 +585,17 @@ function createItem(args, logger, notifier, requestKeys, lambdaContext) {
586
585
return item ;
587
586
}
588
587
588
+ function setCustomItemKeys ( item , custom ) {
589
+ if ( custom && custom . level !== undefined ) {
590
+ item . level = custom . level ;
591
+ delete custom . level ;
592
+ }
593
+ if ( custom && custom . skipFrames !== undefined ) {
594
+ item . skipFrames = custom . skipFrames ;
595
+ delete custom . skipFrames ;
596
+ }
597
+ }
598
+
589
599
var TELEMETRY_TYPES = [ 'log' , 'network' , 'dom' , 'navigation' , 'error' , 'manual' ] ;
590
600
var TELEMETRY_LEVELS = [ 'critical' , 'error' , 'warning' , 'info' , 'debug' ] ;
591
601
@@ -1167,30 +1177,21 @@ function Frame(stackFrame) {
1167
1177
}
1168
1178
1169
1179
1170
- function Stack ( exception ) {
1180
+ function Stack ( exception , skip ) {
1171
1181
function getStack ( ) {
1172
1182
var parserStack = [ ] ;
1173
- var exc ;
1174
1183
1175
- if ( ! exception . stack ) {
1176
- try {
1177
- throw exception ;
1178
- } catch ( e ) {
1179
- exc = e ;
1180
- }
1181
- } else {
1182
- exc = exception ;
1183
- }
1184
+ skip = skip || 0 ;
1184
1185
1185
1186
try {
1186
- parserStack = ErrorStackParser . parse ( exc ) ;
1187
+ parserStack = ErrorStackParser . parse ( exception ) ;
1187
1188
} catch ( e ) {
1188
1189
parserStack = [ ] ;
1189
1190
}
1190
1191
1191
1192
var stack = [ ] ;
1192
1193
1193
- for ( var i = 0 ; i < parserStack . length ; i ++ ) {
1194
+ for ( var i = skip ; i < parserStack . length ; i ++ ) {
1194
1195
stack . push ( new Frame ( parserStack [ i ] ) ) ;
1195
1196
}
1196
1197
@@ -1207,21 +1208,23 @@ function Stack(exception) {
1207
1208
}
1208
1209
1209
1210
1210
- function parse ( e ) {
1211
+ function parse ( e , skip ) {
1211
1212
var err = e ;
1212
1213
1213
1214
if ( err . nested ) {
1214
1215
var traceChain = [ ] ;
1215
1216
while ( err ) {
1216
- traceChain . push ( new Stack ( err ) ) ;
1217
+ traceChain . push ( new Stack ( err , skip ) ) ;
1217
1218
err = err . nested ;
1219
+
1220
+ skip = 0 ; // Only apply skip value to primary error
1218
1221
}
1219
1222
1220
1223
// Return primary error with full trace chain attached.
1221
1224
traceChain [ 0 ] . traceChain = traceChain ;
1222
1225
return traceChain [ 0 ] ;
1223
1226
} else {
1224
- return new Stack ( err ) ;
1227
+ return new Stack ( err , skip ) ;
1225
1228
}
1226
1229
}
1227
1230
@@ -1810,6 +1813,10 @@ Rollbar.prototype._createItem = function(args) {
1810
1813
return _ . createItem ( args , logger , this ) ;
1811
1814
} ;
1812
1815
1816
+ Rollbar . prototype . loadFull = function ( ) {
1817
+ logger . info ( 'Unexpected Rollbar.loadFull() called on a Notifier instance. This can happen when Rollbar is loaded multiple times.' ) ;
1818
+ } ;
1819
+
1813
1820
function _getFirstFunction ( args ) {
1814
1821
for ( var i = 0 , len = args . length ; i < len ; ++ i ) {
1815
1822
if ( _ . isFunction ( args [ i ] ) ) {
@@ -1831,7 +1838,7 @@ function _gWindow() {
1831
1838
/* global __DEFAULT_ENDPOINT__:false */
1832
1839
1833
1840
var defaultOptions = {
1834
- version : "2.14.6 " ,
1841
+ version : "2.15.0 " ,
1835
1842
scrubFields : [ "pw" , "pass" , "passwd" , "password" , "secret" , "confirm_password" , "confirmPassword" , "password_confirmation" , "passwordConfirmation" , "access_token" , "accessToken" , "X-Rollbar-Access-Token" , "secret_key" , "secretKey" , "secretToken" , "cc-number" , "card number" , "cardnumber" , "cardnum" , "ccnum" , "ccnumber" , "cc num" , "creditcardnumber" , "credit card number" , "newcreditcardnumber" , "new credit card" , "creditcardno" , "credit card no" , "card#" , "card #" , "cc-csc" , "cvc" , "cvc2" , "cvv2" , "ccv2" , "security code" , "card verification" , "name on credit card" , "name on card" , "nameoncard" , "cardholder" , "card holder" , "name des karteninhabers" , "ccname" , "card type" , "cardtype" , "cc type" , "cctype" , "payment type" , "expiration date" , "expirationdate" , "expdate" , "cc-exp" , "ccmonth" , "ccyear" ] ,
1836
1843
logLevel : "debug" ,
1837
1844
reportLevel : "debug" ,
@@ -4283,7 +4290,7 @@ function handleItemWithError(item, options, callback) {
4283
4290
item . data = item . data || { } ;
4284
4291
if ( item . err ) {
4285
4292
try {
4286
- item . stackInfo = item . err . _savedStackTrace || errorParser . parse ( item . err ) ;
4293
+ item . stackInfo = item . err . _savedStackTrace || errorParser . parse ( item . err , item . skipFrames ) ;
4287
4294
} catch ( e ) {
4288
4295
logger . error ( 'Error while parsing the error object.' , e ) ;
4289
4296
try {
@@ -4592,9 +4599,9 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
4592
4599
} ( this , function ErrorStackParser ( StackFrame ) {
4593
4600
'use strict' ;
4594
4601
4595
- var FIREFOX_SAFARI_STACK_REGEXP = / ( ^ | @ ) \S + \ :\d + / ;
4596
- var CHROME_IE_STACK_REGEXP = / ^ \s * a t .* ( \S + \ :\d + | \( n a t i v e \) ) / m;
4597
- var SAFARI_NATIVE_CODE_REGEXP = / ^ ( e v a l @ ) ? ( \[ n a t i v e c o d e \ ]) ? $ / ;
4602
+ var FIREFOX_SAFARI_STACK_REGEXP = / ( ^ | @ ) \S + : \d + / ;
4603
+ var CHROME_IE_STACK_REGEXP = / ^ \s * a t .* ( \S + : \d + | \( n a t i v e \) ) / m;
4604
+ var SAFARI_NATIVE_CODE_REGEXP = / ^ ( e v a l @ ) ? ( \[ n a t i v e c o d e ] ) ? $ / ;
4598
4605
4599
4606
return {
4600
4607
/**
@@ -4622,8 +4629,8 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
4622
4629
return [ urlLike ] ;
4623
4630
}
4624
4631
4625
- var regExp = / ( .+ ?) (?: \ :( \d + ) ) ? (?: \ :( \d + ) ) ? $ / ;
4626
- var parts = regExp . exec ( urlLike . replace ( / [ \( \ )] / g, '' ) ) ;
4632
+ var regExp = / ( .+ ?) (?: : ( \d + ) ) ? (?: : ( \d + ) ) ? $ / ;
4633
+ var parts = regExp . exec ( urlLike . replace ( / [ ( ) ] / g, '' ) ) ;
4627
4634
return [ parts [ 1 ] , parts [ 2 ] || undefined , parts [ 3 ] || undefined ] ;
4628
4635
} ,
4629
4636
@@ -4635,7 +4642,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
4635
4642
return filtered . map ( function ( line ) {
4636
4643
if ( line . indexOf ( '(eval ' ) > - 1 ) {
4637
4644
// Throw away eval information until we implement stacktrace.js/stackframe#8
4638
- line = line . replace ( / e v a l c o d e / g, 'eval' ) . replace ( / ( \( e v a l a t [ ^ \ () ] * ) | ( \) \ , .* $ ) / g, '' ) ;
4645
+ line = line . replace ( / e v a l c o d e / g, 'eval' ) . replace ( / ( \( e v a l a t [ ^ ( ) ] * ) | ( \) , .* $ ) / g, '' ) ;
4639
4646
}
4640
4647
var sanitizedLine = line . replace ( / ^ \s + / , '' ) . replace ( / \( e v a l c o d e / g, '(' ) ;
4641
4648
@@ -4670,7 +4677,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
4670
4677
return filtered . map ( function ( line ) {
4671
4678
// Throw away eval information until we implement stacktrace.js/stackframe#8
4672
4679
if ( line . indexOf ( ' > eval' ) > - 1 ) {
4673
- line = line . replace ( / l i n e ( \d + ) (?: > e v a l l i n e \d + ) * > e v a l \ :\d + \ :\d + / g, ':$1' ) ;
4680
+ line = line . replace ( / l i n e ( \d + ) (?: > e v a l l i n e \d + ) * > e v a l : \d + : \d + / g, ':$1' ) ;
4674
4681
}
4675
4682
4676
4683
if ( line . indexOf ( '@' ) === - 1 && line . indexOf ( ':' ) === - 1 ) {
@@ -4758,11 +4765,11 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
4758
4765
var locationParts = this . extractLocation ( tokens . pop ( ) ) ;
4759
4766
var functionCall = ( tokens . shift ( ) || '' ) ;
4760
4767
var functionName = functionCall
4761
- . replace ( / < a n o n y m o u s f u n c t i o n ( : ( \w + ) ) ? > / , '$2' )
4762
- . replace ( / \( [ ^ \ )] * \) / g, '' ) || undefined ;
4768
+ . replace ( / < a n o n y m o u s f u n c t i o n ( : ( \w + ) ) ? > / , '$2' )
4769
+ . replace ( / \( [ ^ ) ] * \) / g, '' ) || undefined ;
4763
4770
var argsRaw ;
4764
- if ( functionCall . match ( / \( ( [ ^ \ )] * ) \) / ) ) {
4765
- argsRaw = functionCall . replace ( / ^ [ ^ \ (] + \( ( [ ^ \ )] * ) \) $ / , '$1' ) ;
4771
+ if ( functionCall . match ( / \( ( [ ^ ) ] * ) \) / ) ) {
4772
+ argsRaw = functionCall . replace ( / ^ [ ^ ( ] + \( ( [ ^ ) ] * ) \) $ / , '$1' ) ;
4766
4773
}
4767
4774
var args = ( argsRaw === undefined || argsRaw === '[arguments not available]' ) ?
4768
4775
undefined : argsRaw . split ( ',' ) ;
@@ -4820,11 +4827,10 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
4820
4827
var props = booleanProps . concat ( numericProps , stringProps , arrayProps ) ;
4821
4828
4822
4829
function StackFrame ( obj ) {
4823
- if ( obj instanceof Object ) {
4824
- for ( var i = 0 ; i < props . length ; i ++ ) {
4825
- if ( obj . hasOwnProperty ( props [ i ] ) && obj [ props [ i ] ] !== undefined ) {
4826
- this [ 'set' + _capitalize ( props [ i ] ) ] ( obj [ props [ i ] ] ) ;
4827
- }
4830
+ if ( ! obj ) return ;
4831
+ for ( var i = 0 ; i < props . length ; i ++ ) {
4832
+ if ( obj [ props [ i ] ] !== undefined ) {
4833
+ this [ 'set' + _capitalize ( props [ i ] ) ] ( obj [ props [ i ] ] ) ;
4828
4834
}
4829
4835
}
4830
4836
}
@@ -5277,6 +5283,9 @@ var defaults = {
5277
5283
networkResponseBody : false ,
5278
5284
networkRequestHeaders : false ,
5279
5285
networkRequestBody : false ,
5286
+ networkErrorOnHttp5xx : false ,
5287
+ networkErrorOnHttp4xx : false ,
5288
+ networkErrorOnHttp0 : false ,
5280
5289
log : true ,
5281
5290
dom : true ,
5282
5291
navigation : true ,
@@ -5543,6 +5552,7 @@ Instrumenter.prototype.instrumentNetwork = function() {
5543
5552
code = code === 1223 ? 204 : code ;
5544
5553
xhr . __rollbar_xhr . status_code = code ;
5545
5554
xhr . __rollbar_event . level = self . telemeter . levelFromStatus ( code ) ;
5555
+ self . errorOnHttpStatus ( xhr . __rollbar_xhr ) ;
5546
5556
} catch ( e ) {
5547
5557
/* ignore possible exception from xhr.status */
5548
5558
}
@@ -5561,6 +5571,9 @@ Instrumenter.prototype.instrumentNetwork = function() {
5561
5571
} else {
5562
5572
xhr . onreadystatechange = onreadystatechangeHandler ;
5563
5573
}
5574
+ if ( xhr . __rollbar_xhr ) {
5575
+ xhr . __rollbar_xhr . stack = ( new Error ( ) ) . stack ;
5576
+ }
5564
5577
return orig . apply ( this , arguments ) ;
5565
5578
}
5566
5579
} , this . replacements , 'network' ) ;
@@ -5616,6 +5629,7 @@ Instrumenter.prototype.instrumentNetwork = function() {
5616
5629
}
5617
5630
}
5618
5631
self . captureNetwork ( metadata , 'fetch' , undefined ) ;
5632
+ metadata . stack = ( new Error ( ) ) . stack ;
5619
5633
return orig . apply ( this , args ) . then ( function ( resp ) {
5620
5634
metadata . end_time_ms = _ . now ( ) ;
5621
5635
metadata . status_code = resp . status ;
@@ -5648,6 +5662,7 @@ Instrumenter.prototype.instrumentNetwork = function() {
5648
5662
metadata . response . headers = headers ;
5649
5663
}
5650
5664
}
5665
+ self . errorOnHttpStatus ( metadata ) ;
5651
5666
return resp ;
5652
5667
} ) ;
5653
5668
} ;
@@ -5695,6 +5710,18 @@ Instrumenter.prototype.fetchHeaders = function(inHeaders, headersConfig) {
5695
5710
return outHeaders ;
5696
5711
}
5697
5712
5713
+ Instrumenter . prototype . errorOnHttpStatus = function ( metadata ) {
5714
+ var status = metadata . status_code ;
5715
+
5716
+ if ( ( status >= 500 && this . autoInstrument . networkErrorOnHttp5xx ) ||
5717
+ ( status >= 400 && this . autoInstrument . networkErrorOnHttp4xx ) ||
5718
+ ( status === 0 && this . autoInstrument . networkErrorOnHttp0 ) ) {
5719
+ var error = new Error ( 'HTTP request failed with Status ' + status ) ;
5720
+ error . stack = metadata . stack ;
5721
+ this . rollbar . error ( error , { skipFrames : 1 } ) ;
5722
+ }
5723
+ }
5724
+
5698
5725
Instrumenter . prototype . deinstrumentConsole = function ( ) {
5699
5726
if ( ! ( 'console' in this . _window && this . _window . console . log ) ) {
5700
5727
return ;
0 commit comments