rollbar 2.26.2 → 2.26.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/.github/workflows/ci.yml +32 -10
  2. package/.lgtm.yml +7 -7
  3. package/.prettierignore +18 -0
  4. package/.vscode/settings.json +39 -0
  5. package/CHANGELOG.md +121 -35
  6. package/Gruntfile.js +51 -71
  7. package/README.md +2 -4
  8. package/bower.json +1 -3
  9. package/defaults.js +17 -5
  10. package/dist/plugins/jquery.min.js +1 -1
  11. package/dist/rollbar.js +5699 -5052
  12. package/dist/rollbar.js.map +1 -1
  13. package/dist/rollbar.min.js +1 -1
  14. package/dist/rollbar.min.js.map +1 -1
  15. package/dist/rollbar.named-amd.js +5704 -5062
  16. package/dist/rollbar.named-amd.js.map +1 -1
  17. package/dist/rollbar.named-amd.min.js +1 -1
  18. package/dist/rollbar.named-amd.min.js.map +1 -1
  19. package/dist/rollbar.noconflict.umd.js +5693 -5052
  20. package/dist/rollbar.noconflict.umd.js.map +1 -1
  21. package/dist/rollbar.noconflict.umd.min.js +1 -1
  22. package/dist/rollbar.noconflict.umd.min.js.map +1 -1
  23. package/dist/rollbar.snippet.js +1 -1
  24. package/dist/rollbar.umd.js +5704 -5063
  25. package/dist/rollbar.umd.js.map +1 -1
  26. package/dist/rollbar.umd.min.js +1 -1
  27. package/dist/rollbar.umd.min.js.map +1 -1
  28. package/docs/extension-exceptions.md +35 -30
  29. package/docs/migration_v0_to_v1.md +41 -38
  30. package/index.d.ts +270 -231
  31. package/karma.conf.js +16 -34
  32. package/package.json +21 -17
  33. package/prettier.config.js +7 -0
  34. package/src/api.js +21 -10
  35. package/src/apiUtility.js +12 -8
  36. package/src/browser/core.js +103 -65
  37. package/src/browser/defaults/scrubFields.js +3 -3
  38. package/src/browser/detection.js +7 -8
  39. package/src/browser/domUtility.js +18 -8
  40. package/src/browser/globalSetup.js +12 -6
  41. package/src/browser/logger.js +1 -1
  42. package/src/browser/plugins/jquery.js +35 -35
  43. package/src/browser/predicates.js +1 -1
  44. package/src/browser/rollbar.js +1 -1
  45. package/src/browser/rollbarWrapper.js +8 -5
  46. package/src/browser/shim.js +43 -19
  47. package/src/browser/snippet_callback.js +6 -4
  48. package/src/browser/telemetry.js +573 -354
  49. package/src/browser/transforms.js +46 -27
  50. package/src/browser/transport/fetch.js +16 -14
  51. package/src/browser/transport/xhr.js +29 -13
  52. package/src/browser/transport.js +82 -25
  53. package/src/browser/url.js +16 -8
  54. package/src/browser/wrapGlobals.js +27 -8
  55. package/src/defaults.js +3 -3
  56. package/src/errorParser.js +14 -11
  57. package/src/merge.js +32 -23
  58. package/src/notifier.js +16 -13
  59. package/src/predicates.js +43 -23
  60. package/src/queue.js +71 -39
  61. package/src/rateLimiter.js +59 -18
  62. package/src/react-native/logger.js +1 -1
  63. package/src/react-native/rollbar.js +59 -55
  64. package/src/react-native/transforms.js +13 -9
  65. package/src/react-native/transport.js +44 -34
  66. package/src/rollbar.js +22 -13
  67. package/src/scrub.js +0 -1
  68. package/src/server/locals.js +69 -39
  69. package/src/server/logger.js +4 -4
  70. package/src/server/parser.js +72 -47
  71. package/src/server/rollbar.js +133 -55
  72. package/src/server/sourceMap/stackTrace.js +33 -18
  73. package/src/server/telemetry/urlHelpers.js +9 -11
  74. package/src/server/telemetry.js +68 -45
  75. package/src/server/transforms.js +37 -21
  76. package/src/server/transport.js +62 -32
  77. package/src/telemetry.js +92 -28
  78. package/src/transforms.js +33 -21
  79. package/src/truncation.js +8 -5
  80. package/src/utility/headers.js +43 -43
  81. package/src/utility/replace.js +9 -0
  82. package/src/utility/traverse.js +1 -1
  83. package/src/utility.js +89 -52
  84. package/test/api.test.js +31 -29
  85. package/test/apiUtility.test.js +43 -44
  86. package/test/browser.core.test.js +141 -131
  87. package/test/browser.domUtility.test.js +52 -35
  88. package/test/browser.predicates.test.js +13 -13
  89. package/test/browser.rollbar.test.js +597 -503
  90. package/test/browser.telemetry.test.js +76 -0
  91. package/test/browser.transforms.test.js +146 -128
  92. package/test/browser.transport.test.js +54 -46
  93. package/test/browser.url.test.js +12 -11
  94. package/test/fixtures/locals.fixtures.js +245 -126
  95. package/test/notifier.test.js +90 -78
  96. package/test/predicates.test.js +260 -214
  97. package/test/queue.test.js +230 -214
  98. package/test/rateLimiter.test.js +50 -42
  99. package/test/react-native.rollbar.test.js +149 -115
  100. package/test/react-native.transforms.test.js +21 -23
  101. package/test/react-native.transport.test.js +23 -11
  102. package/test/server.lambda.test.js +70 -53
  103. package/test/server.locals.test.js +437 -210
  104. package/test/server.parser.test.js +32 -26
  105. package/test/server.predicates.test.js +45 -43
  106. package/test/server.rollbar.test.js +311 -259
  107. package/test/server.telemetry.test.js +208 -83
  108. package/test/server.transforms.test.js +455 -361
  109. package/test/server.transport.test.js +144 -76
  110. package/test/telemetry.test.js +46 -37
  111. package/test/transforms.test.js +68 -66
  112. package/test/truncation.test.js +55 -53
  113. package/test/utility.test.js +266 -222
  114. package/webpack.config.js +46 -43
  115. package/.gitmodules +0 -3
  116. package/browserstack.browsers.js +0 -153
  117. package/browserstack.browsers.json +0 -4384
@@ -1,13 +1,14 @@
1
1
  var http = require('http');
2
2
  var https = require('https');
3
3
  var _ = require('../utility');
4
+ var replace = require('../utility/replace');
4
5
  var urlHelpers = require('./telemetry/urlHelpers');
5
6
 
6
7
  var defaults = {
7
8
  network: true,
8
9
  networkResponseHeaders: false,
9
10
  networkRequestHeaders: false,
10
- log: true
11
+ log: true,
11
12
  };
12
13
 
13
14
  function Instrumenter(options, telemeter, rollbar) {
@@ -26,11 +27,11 @@ function Instrumenter(options, telemeter, rollbar) {
26
27
  this.diagnostic = rollbar.client.notifier.diagnostic;
27
28
  this.replacements = {
28
29
  network: [],
29
- log: []
30
+ log: [],
30
31
  };
31
32
  }
32
33
 
33
- Instrumenter.prototype.configure = function(options) {
34
+ Instrumenter.prototype.configure = function (options) {
34
35
  this.options = _.merge(this.options, options);
35
36
  var autoInstrument = options.autoInstrument;
36
37
  var oldSettings = _.merge(this.autoInstrument);
@@ -45,10 +46,14 @@ Instrumenter.prototype.configure = function(options) {
45
46
  this.instrument(oldSettings);
46
47
  };
47
48
 
48
- Instrumenter.prototype.instrument = function(oldSettings) {
49
+ Instrumenter.prototype.instrument = function (oldSettings) {
49
50
  if (this.autoInstrument.network && !(oldSettings && oldSettings.network)) {
50
51
  this.instrumentNetwork();
51
- } else if (!this.autoInstrument.network && oldSettings && oldSettings.network) {
52
+ } else if (
53
+ !this.autoInstrument.network &&
54
+ oldSettings &&
55
+ oldSettings.network
56
+ ) {
52
57
  this.deinstrumentNetwork();
53
58
  }
54
59
 
@@ -59,20 +64,32 @@ Instrumenter.prototype.instrument = function(oldSettings) {
59
64
  }
60
65
  };
61
66
 
62
- Instrumenter.prototype.deinstrumentNetwork = function() {
67
+ Instrumenter.prototype.deinstrumentNetwork = function () {
63
68
  restore(this.replacements, 'network');
64
69
  };
65
70
 
66
- Instrumenter.prototype.instrumentNetwork = function() {
67
- replace(http, 'request', networkRequestWrapper.bind(this), this.replacements, 'network');
68
- replace(https, 'request', networkRequestWrapper.bind(this), this.replacements, 'network');
71
+ Instrumenter.prototype.instrumentNetwork = function () {
72
+ replace(
73
+ http,
74
+ 'request',
75
+ networkRequestWrapper.bind(this),
76
+ this.replacements,
77
+ 'network',
78
+ );
79
+ replace(
80
+ https,
81
+ 'request',
82
+ networkRequestWrapper.bind(this),
83
+ this.replacements,
84
+ 'network',
85
+ );
69
86
  };
70
87
 
71
88
  function networkRequestWrapper(orig) {
72
89
  var telemeter = this.telemeter;
73
90
  var self = this;
74
91
 
75
- return function(url, options, cb) {
92
+ return function (url, options, cb) {
76
93
  var mergedOptions = urlHelpers.mergeOptions(url, options, cb);
77
94
 
78
95
  var metadata = {
@@ -80,7 +97,7 @@ function networkRequestWrapper(orig) {
80
97
  url: urlHelpers.constructUrl(mergedOptions.options),
81
98
  status_code: null,
82
99
  start_time_ms: _.now(),
83
- end_time_ms: null
100
+ end_time_ms: null,
84
101
  };
85
102
 
86
103
  if (self.autoInstrument.networkRequestHeaders) {
@@ -90,20 +107,24 @@ function networkRequestWrapper(orig) {
90
107
 
91
108
  // Call the original method with the original arguments and wrapped callback.
92
109
  var wrappedArgs = Array.from(arguments);
93
- var wrappedCallback = responseCallbackWrapper(self.autoInstrument, metadata, mergedOptions.cb);
110
+ var wrappedCallback = responseCallbackWrapper(
111
+ self.autoInstrument,
112
+ metadata,
113
+ mergedOptions.cb,
114
+ );
94
115
  if (mergedOptions.cb) {
95
116
  wrappedArgs.pop();
96
117
  }
97
118
  wrappedArgs.push(wrappedCallback);
98
119
  var req = orig.apply(https, wrappedArgs);
99
120
 
100
- req.on('error', err => {
121
+ req.on('error', (err) => {
101
122
  metadata.status_code = 0;
102
- metadata.error = [err.name, err.message].join(': ') ;
123
+ metadata.error = [err.name, err.message].join(': ');
103
124
  });
104
125
 
105
126
  return req;
106
- }
127
+ };
107
128
  }
108
129
 
109
130
  function responseCallbackWrapper(options, metadata, callback) {
@@ -118,51 +139,53 @@ function responseCallbackWrapper(options, metadata, callback) {
118
139
  if (callback) {
119
140
  return callback.apply(undefined, arguments);
120
141
  }
121
- }
142
+ };
122
143
  }
123
144
 
124
- Instrumenter.prototype.captureNetwork = function(metadata, subtype, rollbarUUID) {
145
+ Instrumenter.prototype.captureNetwork = function (
146
+ metadata,
147
+ subtype,
148
+ rollbarUUID,
149
+ ) {
125
150
  return this.telemeter.captureNetwork(metadata, subtype, rollbarUUID);
126
151
  };
127
152
 
128
- Instrumenter.prototype.deinstrumentConsole = function() {
153
+ Instrumenter.prototype.deinstrumentConsole = function () {
129
154
  restore(this.replacements, 'log');
130
155
  };
131
156
 
132
- Instrumenter.prototype.instrumentConsole = function() {
157
+ Instrumenter.prototype.instrumentConsole = function () {
133
158
  var telemeter = this.telemeter;
134
159
 
135
160
  var stdout = process.stdout;
136
- replace(stdout, 'write', function(orig) {
137
- return function(string) {
138
- telemeter.captureLog(string, 'info');
139
- return orig.apply(stdout, arguments);
140
- }
141
- }, this.replacements, 'log');
161
+ replace(
162
+ stdout,
163
+ 'write',
164
+ function (orig) {
165
+ return function (string) {
166
+ telemeter.captureLog(string, 'info');
167
+ return orig.apply(stdout, arguments);
168
+ };
169
+ },
170
+ this.replacements,
171
+ 'log',
172
+ );
142
173
 
143
174
  var stderr = process.stderr;
144
- replace(stderr, 'write', function(orig) {
145
- return function(string) {
146
- telemeter.captureLog(string, 'error');
147
- return orig.apply(stderr, arguments);
148
- }
149
- }, this.replacements, 'log');
175
+ replace(
176
+ stderr,
177
+ 'write',
178
+ function (orig) {
179
+ return function (string) {
180
+ telemeter.captureLog(string, 'error');
181
+ return orig.apply(stderr, arguments);
182
+ };
183
+ },
184
+ this.replacements,
185
+ 'log',
186
+ );
150
187
  };
151
188
 
152
- // TODO: These helpers are duplicated in src/browser/telemetry.js,
153
- // and may be candidates for extraction into a shared module.
154
- // It is recommended that before doing so, the author should allow
155
- // for more telemetry types to be implemented for the Node target
156
- // to ensure that the implementations of these helpers don't diverge.
157
- // If they do diverge, there's little point in the shared module.
158
- function replace(obj, name, replacement, replacements, type) {
159
- var orig = obj[name];
160
- obj[name] = replacement(orig);
161
- if (replacements) {
162
- replacements[type].push([obj, name, orig]);
163
- }
164
- }
165
-
166
189
  function restore(replacements, type) {
167
190
  var b;
168
191
  while (replacements[type].length) {
@@ -6,7 +6,8 @@ var _ = require('../utility');
6
6
  var scrub = require('../scrub');
7
7
 
8
8
  function baseData(item, options, callback) {
9
- var environment = (options.payload && options.payload.environment) || options.environment;
9
+ var environment =
10
+ (options.payload && options.payload.environment) || options.environment;
10
11
  var data = {
11
12
  timestamp: Math.round(item.timestamp / 1000),
12
13
  environment: item.environment || environment,
@@ -15,7 +16,7 @@ function baseData(item, options, callback) {
15
16
  framework: item.framework || options.framework,
16
17
  uuid: item.uuid,
17
18
  notifier: JSON.parse(JSON.stringify(options.notifier)),
18
- custom: item.custom
19
+ custom: item.custom,
19
20
  };
20
21
 
21
22
  if (options.codeVersion) {
@@ -34,7 +35,7 @@ function baseData(item, options, callback) {
34
35
  data.server = {
35
36
  host: options.host,
36
37
  argv: process.argv.concat(),
37
- pid: process.pid
38
+ pid: process.pid,
38
39
  };
39
40
 
40
41
  if (options.branch) {
@@ -53,7 +54,7 @@ function addMessageData(item, options, callback) {
53
54
  item.data.body = item.data.body || {};
54
55
  var message = item.message || 'Item sent with null or missing arguments.';
55
56
  item.data.body.message = {
56
- body: message
57
+ body: message,
57
58
  };
58
59
  callback(null, item);
59
60
  }
@@ -93,9 +94,13 @@ function handleItemWithError(item, options, callback) {
93
94
  _.addErrorContext(item, errors);
94
95
  }
95
96
 
96
- var cb = function(e) {
97
+ var cb = function (e) {
97
98
  if (e) {
98
- item.message = item.err.message || item.err.description || item.message || String(item.err);
99
+ item.message =
100
+ item.err.message ||
101
+ item.err.description ||
102
+ item.message ||
103
+ String(item.err);
99
104
  item.diagnostic.buildTraceData = e.message;
100
105
  delete item.stackInfo;
101
106
  }
@@ -129,11 +134,13 @@ function addRequestData(item, options, callback) {
129
134
 
130
135
  if (req.route) {
131
136
  routePath = req.route.path;
132
- item.data.context = baseUrl && baseUrl.length ? baseUrl + routePath : routePath;
137
+ item.data.context =
138
+ baseUrl && baseUrl.length ? baseUrl + routePath : routePath;
133
139
  } else {
134
140
  try {
135
141
  routePath = req.app._router.matchRequest(req).path;
136
- item.data.context = baseUrl && baseUrl.length ? baseUrl + routePath : routePath;
142
+ item.data.context =
143
+ baseUrl && baseUrl.length ? baseUrl + routePath : routePath;
137
144
  } catch (ignore) {
138
145
  // Ignored
139
146
  }
@@ -151,7 +158,7 @@ function addRequestData(item, options, callback) {
151
158
  }
152
159
  item.data.person = person;
153
160
  } else if (req.user) {
154
- item.data.person = {id: req.user.id};
161
+ item.data.person = { id: req.user.id };
155
162
  if (req.user.username && captureUsername) {
156
163
  item.data.person.username = req.user.username;
157
164
  }
@@ -163,7 +170,7 @@ function addRequestData(item, options, callback) {
163
170
  if (_.isFunction(userId)) {
164
171
  userId = userId();
165
172
  }
166
- item.data.person = {id: userId};
173
+ item.data.person = { id: userId };
167
174
  }
168
175
 
169
176
  callback(null, item);
@@ -182,7 +189,7 @@ function addLambdaData(item, options, callback) {
182
189
  functionName: c.functionName,
183
190
  functionVersion: c.functionVersion,
184
191
  arn: c.invokedFunctionArn,
185
- requestId: c.awsRequestId
192
+ requestId: c.awsRequestId,
186
193
  };
187
194
 
188
195
  item.data = item.data || {};
@@ -206,7 +213,9 @@ function scrubPayload(item, options, callback) {
206
213
  }
207
214
 
208
215
  function parseRequestBody(req, options) {
209
- if (!req || !options.scrubRequestBody) { return }
216
+ if (!req || !options.scrubRequestBody) {
217
+ return;
218
+ }
210
219
 
211
220
  try {
212
221
  if (_.isString(req.body) && _isJsonContentType(req)) {
@@ -219,7 +228,9 @@ function parseRequestBody(req, options) {
219
228
  }
220
229
 
221
230
  function serializeRequestBody(req, options) {
222
- if (!req || !options.scrubRequestBody) { return }
231
+ if (!req || !options.scrubRequestBody) {
232
+ return;
233
+ }
223
234
 
224
235
  try {
225
236
  if (_.isObject(req.body) && _isJsonContentType(req)) {
@@ -234,11 +245,15 @@ function serializeRequestBody(req, options) {
234
245
  /** Helpers **/
235
246
 
236
247
  function _isJsonContentType(req) {
237
- return req.headers && req.headers['content-type'] && req.headers['content-type'].includes('json');
248
+ return (
249
+ req.headers &&
250
+ req.headers['content-type'] &&
251
+ req.headers['content-type'].includes('json')
252
+ );
238
253
  }
239
254
 
240
255
  function _buildTraceData(chain, options, item) {
241
- return function(ex, cb) {
256
+ return function (ex, cb) {
242
257
  parser.parseException(ex, options, item, function (err, errData) {
243
258
  if (err) {
244
259
  return cb(err);
@@ -248,8 +263,8 @@ function _buildTraceData(chain, options, item) {
248
263
  frames: errData.frames,
249
264
  exception: {
250
265
  class: errData['class'],
251
- message: errData.message
252
- }
266
+ message: errData.message,
267
+ },
253
268
  });
254
269
 
255
270
  return cb(null);
@@ -268,11 +283,12 @@ function _extractIp(req) {
268
283
  function _buildRequestData(req) {
269
284
  var headers = req.headers || {};
270
285
  var host = headers.host || '<no host>';
271
- var proto = req.protocol || ((req.socket && req.socket.encrypted) ? 'https' : 'http' );
286
+ var proto =
287
+ req.protocol || (req.socket && req.socket.encrypted ? 'https' : 'http');
272
288
  var parsedUrl;
273
289
  var baseUrl = req.baseUrl || '';
274
290
  if (_.isType(req.url, 'string')) {
275
- var fullUrl = baseUrl && baseUrl.length ? baseUrl + req.url : req.url
291
+ var fullUrl = baseUrl && baseUrl.length ? baseUrl + req.url : req.url;
276
292
  parsedUrl = url.parse(fullUrl, true);
277
293
  } else {
278
294
  parsedUrl = req.url || {};
@@ -284,7 +300,7 @@ function _buildRequestData(req) {
284
300
  url: reqUrl,
285
301
  user_ip: _extractIp(req),
286
302
  headers: headers,
287
- method: req.method
303
+ method: req.method,
288
304
  };
289
305
  if (parsedUrl.search && parsedUrl.search.length > 0) {
290
306
  data.GET = parsedUrl.query;
@@ -315,5 +331,5 @@ module.exports = {
315
331
  addErrorData: addErrorData,
316
332
  addRequestData: addRequestData,
317
333
  addLambdaData: addLambdaData,
318
- scrubPayload: scrubPayload
334
+ scrubPayload: scrubPayload,
319
335
  };
@@ -28,10 +28,16 @@ function Transport() {
28
28
  this.rateLimitExpires = 0;
29
29
  }
30
30
 
31
- Transport.prototype.get = function(accessToken, options, params, callback, transportFactory) {
31
+ Transport.prototype.get = function (
32
+ accessToken,
33
+ options,
34
+ params,
35
+ callback,
36
+ transportFactory,
37
+ ) {
32
38
  var t;
33
39
  if (!callback || !_.isFunction(callback)) {
34
- callback = function() {};
40
+ callback = function () {};
35
41
  }
36
42
  options = options || {};
37
43
  _.addParamsAndAccessTokenToPath(accessToken, options, params);
@@ -42,22 +48,33 @@ Transport.prototype.get = function(accessToken, options, params, callback, trans
42
48
  t = _transport(options);
43
49
  }
44
50
  if (!t) {
45
- logger.error('Unknown transport based on given protocol: ' + options.protocol);
51
+ logger.error(
52
+ 'Unknown transport based on given protocol: ' + options.protocol,
53
+ );
46
54
  return callback(new Error('Unknown transport'));
47
55
  }
48
- var req = t.request(options, function(resp) {
49
- this.handleResponse(resp, callback);
50
- }.bind(this));
51
- req.on('error', function(err) {
56
+ var req = t.request(
57
+ options,
58
+ function (resp) {
59
+ this.handleResponse(resp, callback);
60
+ }.bind(this),
61
+ );
62
+ req.on('error', function (err) {
52
63
  callback(err);
53
64
  });
54
65
  req.end();
55
- }
56
-
57
- Transport.prototype.post = function(accessToken, options, payload, callback, transportFactory) {
66
+ };
67
+
68
+ Transport.prototype.post = function (
69
+ accessToken,
70
+ options,
71
+ payload,
72
+ callback,
73
+ transportFactory,
74
+ ) {
58
75
  var t;
59
76
  if (!callback || !_.isFunction(callback)) {
60
- callback = function() {};
77
+ callback = function () {};
61
78
  }
62
79
  if (_currentTime() < this.rateLimitExpires) {
63
80
  return callback(new Error('Exceeded rate limit'));
@@ -79,47 +96,55 @@ Transport.prototype.post = function(accessToken, options, payload, callback, tra
79
96
  t = _transport(options);
80
97
  }
81
98
  if (!t) {
82
- logger.error('Unknown transport based on given protocol: ' + options.protocol);
99
+ logger.error(
100
+ 'Unknown transport based on given protocol: ' + options.protocol,
101
+ );
83
102
  return callback(new Error('Unknown transport'));
84
103
  }
85
- var req = t.request(options, function(resp) {
86
- this.handleResponse(resp, _wrapPostCallback(callback));
87
- }.bind(this));
88
- req.on('error', function(err) {
104
+ var req = t.request(
105
+ options,
106
+ function (resp) {
107
+ this.handleResponse(resp, _wrapPostCallback(callback));
108
+ }.bind(this),
109
+ );
110
+ req.on('error', function (err) {
89
111
  callback(err);
90
112
  });
91
113
  if (writeData) {
92
114
  req.write(writeData);
93
115
  }
94
116
  req.end();
95
- }
117
+ };
96
118
 
97
- Transport.prototype.updateRateLimit = function(resp) {
119
+ Transport.prototype.updateRateLimit = function (resp) {
98
120
  var remaining = parseInt(resp.headers['x-rate-limit-remaining'] || 0);
99
- var remainingSeconds = Math.min(MAX_RATE_LIMIT_INTERVAL, resp.headers['x-rate-limit-remaining-seconds'] || 0);
121
+ var remainingSeconds = Math.min(
122
+ MAX_RATE_LIMIT_INTERVAL,
123
+ resp.headers['x-rate-limit-remaining-seconds'] || 0,
124
+ );
100
125
  var currentTime = _currentTime();
101
126
 
102
- if ((resp.statusCode === 429) && (remaining === 0)) {
127
+ if (resp.statusCode === 429 && remaining === 0) {
103
128
  this.rateLimitExpires = currentTime + remainingSeconds;
104
129
  } else {
105
130
  this.rateLimitExpires = currentTime;
106
131
  }
107
- }
132
+ };
108
133
 
109
- Transport.prototype.handleResponse = function(resp, callback) {
134
+ Transport.prototype.handleResponse = function (resp, callback) {
110
135
  this.updateRateLimit(resp);
111
136
 
112
137
  var respData = [];
113
138
  resp.setEncoding('utf8');
114
- resp.on('data', function(chunk) {
139
+ resp.on('data', function (chunk) {
115
140
  respData.push(chunk);
116
141
  });
117
142
 
118
- resp.on('end', function() {
143
+ resp.on('end', function () {
119
144
  respData = respData.join('');
120
145
  _parseApiResponse(respData, callback);
121
146
  });
122
- }
147
+ };
123
148
 
124
149
  /** Helpers **/
125
150
 
@@ -138,7 +163,7 @@ function _headers(accessToken, options, data) {
138
163
  }
139
164
 
140
165
  function _transport(options) {
141
- return {'http:': http, 'https:': https}[options.protocol];
166
+ return { 'http:': http, 'https:': https }[options.protocol];
142
167
  }
143
168
 
144
169
  function _parseApiResponse(data, callback) {
@@ -151,27 +176,32 @@ function _parseApiResponse(data, callback) {
151
176
 
152
177
  if (data.err) {
153
178
  logger.error('Received error: ' + data.message);
154
- return callback(new Error('Api error: ' + (data.message || 'Unknown error')));
179
+ return callback(
180
+ new Error('Api error: ' + (data.message || 'Unknown error')),
181
+ );
155
182
  }
156
183
 
157
184
  callback(null, data);
158
185
  }
159
186
 
160
187
  function _wrapPostCallback(callback) {
161
- return function(err, data) {
188
+ return function (err, data) {
162
189
  if (err) {
163
190
  return callback(err);
164
191
  }
165
192
  if (data.result && data.result.uuid) {
166
- logger.log([
193
+ logger.log(
194
+ [
167
195
  'Successful api response.',
168
- ' Link: https://rollbar.com/occurrence/uuid/?uuid=' + data.result.uuid
169
- ].join(''));
196
+ ' Link: https://rollbar.com/occurrence/uuid/?uuid=' +
197
+ data.result.uuid,
198
+ ].join(''),
199
+ );
170
200
  } else {
171
201
  logger.log('Successful api response');
172
202
  }
173
203
  callback(null, data.result);
174
- }
204
+ };
175
205
  }
176
206
 
177
207
  function _currentTime() {