rollbar 2.26.3 → 3.0.0-alpha.1

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 (186) hide show
  1. package/.cursor/rules/guidelines.mdc +154 -0
  2. package/.github/workflows/ci.yml +32 -12
  3. package/.lgtm.yml +7 -7
  4. package/.prettierignore +18 -0
  5. package/.vscode/settings.json +39 -0
  6. package/CHANGELOG.md +121 -35
  7. package/CLAUDE.md +201 -0
  8. package/Gruntfile.js +101 -48
  9. package/Makefile +3 -3
  10. package/README.md +2 -4
  11. package/SECURITY.md +5 -0
  12. package/babel.config.json +9 -0
  13. package/bower.json +1 -3
  14. package/codex.md +148 -0
  15. package/defaults.js +17 -5
  16. package/dist/plugins/jquery.min.js +1 -1
  17. package/dist/rollbar.js +18748 -5375
  18. package/dist/rollbar.js.map +1 -1
  19. package/dist/rollbar.min.js +2 -1
  20. package/dist/rollbar.min.js.LICENSE.txt +1 -0
  21. package/dist/rollbar.min.js.map +1 -1
  22. package/dist/rollbar.named-amd.js +19368 -6000
  23. package/dist/rollbar.named-amd.js.map +1 -1
  24. package/dist/rollbar.named-amd.min.js +3 -1
  25. package/dist/rollbar.named-amd.min.js.LICENSE.txt +1 -0
  26. package/dist/rollbar.named-amd.min.js.map +1 -1
  27. package/dist/rollbar.noconflict.umd.js +18749 -5380
  28. package/dist/rollbar.noconflict.umd.js.map +1 -1
  29. package/dist/rollbar.noconflict.umd.min.js +3 -1
  30. package/dist/rollbar.noconflict.umd.min.js.LICENSE.txt +1 -0
  31. package/dist/rollbar.noconflict.umd.min.js.map +1 -1
  32. package/dist/rollbar.snippet.js +1 -1
  33. package/dist/rollbar.umd.js +19367 -6000
  34. package/dist/rollbar.umd.js.map +1 -1
  35. package/dist/rollbar.umd.min.js +3 -1
  36. package/dist/rollbar.umd.min.js.LICENSE.txt +1 -0
  37. package/dist/rollbar.umd.min.js.map +1 -1
  38. package/docs/extension-exceptions.md +35 -30
  39. package/docs/migration_v0_to_v1.md +41 -38
  40. package/eslint.config.mjs +33 -0
  41. package/get_versions.js +33 -0
  42. package/index.d.ts +270 -231
  43. package/karma.conf.js +18 -27
  44. package/package.json +21 -21
  45. package/prettier.config.js +7 -0
  46. package/src/api.js +78 -14
  47. package/src/apiUtility.js +14 -11
  48. package/src/browser/core.js +138 -72
  49. package/src/browser/defaults/scrubFields.js +3 -3
  50. package/src/browser/detection.js +7 -8
  51. package/src/browser/domUtility.js +18 -8
  52. package/src/browser/globalSetup.js +12 -6
  53. package/src/browser/logger.js +1 -1
  54. package/src/browser/plugins/jquery.js +35 -35
  55. package/src/browser/predicates.js +1 -1
  56. package/src/browser/replay/defaults.js +71 -0
  57. package/src/browser/replay/recorder.js +193 -0
  58. package/src/browser/replay/replayMap.js +195 -0
  59. package/src/browser/rollbar.js +12 -8
  60. package/src/browser/rollbarWrapper.js +8 -5
  61. package/src/browser/shim.js +43 -19
  62. package/src/browser/snippet_callback.js +6 -4
  63. package/src/browser/telemetry.js +573 -361
  64. package/src/browser/transforms.js +46 -27
  65. package/src/browser/transport/fetch.js +26 -14
  66. package/src/browser/transport/xhr.js +41 -14
  67. package/src/browser/transport.js +93 -33
  68. package/src/browser/url.js +16 -8
  69. package/src/browser/wrapGlobals.js +27 -8
  70. package/src/defaults.js +3 -3
  71. package/src/errorParser.js +14 -11
  72. package/src/merge.js +32 -23
  73. package/src/notifier.js +16 -13
  74. package/src/predicates.js +43 -23
  75. package/src/queue.js +133 -40
  76. package/src/rateLimiter.js +59 -18
  77. package/src/react-native/logger.js +1 -1
  78. package/src/react-native/rollbar.js +59 -55
  79. package/src/react-native/transforms.js +13 -9
  80. package/src/react-native/transport.js +44 -34
  81. package/src/rollbar.js +72 -21
  82. package/src/scrub.js +0 -1
  83. package/src/server/locals.js +69 -39
  84. package/src/server/logger.js +4 -4
  85. package/src/server/parser.js +72 -47
  86. package/src/server/rollbar.js +135 -56
  87. package/src/server/sourceMap/stackTrace.js +33 -18
  88. package/src/server/telemetry/urlHelpers.js +9 -11
  89. package/src/server/telemetry.js +68 -45
  90. package/src/server/transforms.js +37 -21
  91. package/src/server/transport.js +62 -32
  92. package/src/telemetry.js +162 -33
  93. package/src/tracing/context.js +24 -0
  94. package/src/tracing/contextManager.js +37 -0
  95. package/src/tracing/defaults.js +7 -0
  96. package/src/tracing/exporter.js +188 -0
  97. package/src/tracing/hrtime.js +98 -0
  98. package/src/tracing/id.js +24 -0
  99. package/src/tracing/session.js +55 -0
  100. package/src/tracing/span.js +92 -0
  101. package/src/tracing/spanProcessor.js +15 -0
  102. package/src/tracing/tracer.js +46 -0
  103. package/src/tracing/tracing.js +89 -0
  104. package/src/transforms.js +33 -21
  105. package/src/truncation.js +8 -5
  106. package/src/utility/headers.js +43 -43
  107. package/src/utility/replace.js +9 -0
  108. package/src/utility/traverse.js +1 -1
  109. package/src/utility.js +123 -52
  110. package/test/api.test.js +88 -41
  111. package/test/apiUtility.test.js +48 -50
  112. package/test/browser.core.test.js +142 -141
  113. package/test/browser.domUtility.test.js +53 -36
  114. package/test/browser.predicates.test.js +14 -14
  115. package/test/browser.replay.recorder.test.js +416 -0
  116. package/test/browser.rollbar.test.js +655 -515
  117. package/test/browser.telemetry.test.js +46 -39
  118. package/test/browser.transforms.test.js +164 -139
  119. package/test/browser.transport.test.js +59 -50
  120. package/test/browser.url.test.js +13 -12
  121. package/test/fixtures/locals.fixtures.js +245 -126
  122. package/test/fixtures/replay/index.js +20 -0
  123. package/test/fixtures/replay/payloads.fixtures.js +229 -0
  124. package/test/fixtures/replay/rrwebEvents.fixtures.js +251 -0
  125. package/test/fixtures/replay/rrwebSyntheticEvents.fixtures.js +328 -0
  126. package/test/notifier.test.js +91 -79
  127. package/test/predicates.test.js +261 -215
  128. package/test/queue.test.js +231 -215
  129. package/test/rateLimiter.test.js +51 -43
  130. package/test/react-native.rollbar.test.js +150 -116
  131. package/test/react-native.transforms.test.js +23 -25
  132. package/test/react-native.transport.test.js +26 -14
  133. package/test/replay/index.js +2 -0
  134. package/test/replay/integration/api.spans.test.js +136 -0
  135. package/test/replay/integration/e2e.test.js +228 -0
  136. package/test/replay/integration/index.js +9 -0
  137. package/test/replay/integration/queue.replayMap.test.js +332 -0
  138. package/test/replay/integration/replayMap.test.js +163 -0
  139. package/test/replay/integration/sessionRecording.test.js +390 -0
  140. package/test/replay/unit/api.postSpans.test.js +150 -0
  141. package/test/replay/unit/index.js +7 -0
  142. package/test/replay/unit/queue.replayMap.test.js +225 -0
  143. package/test/replay/unit/replayMap.test.js +348 -0
  144. package/test/replay/util/index.js +5 -0
  145. package/test/replay/util/mockRecordFn.js +80 -0
  146. package/test/server.lambda.mocha.test.mjs +172 -0
  147. package/test/server.locals.constructor.mocha.test.mjs +80 -0
  148. package/test/server.locals.error-handling.mocha.test.mjs +387 -0
  149. package/test/server.locals.merge.mocha.test.mjs +267 -0
  150. package/test/server.locals.test-utils.mjs +114 -0
  151. package/test/server.parser.mocha.test.mjs +87 -0
  152. package/test/server.predicates.mocha.test.mjs +63 -0
  153. package/test/server.rollbar.constructor.mocha.test.mjs +199 -0
  154. package/test/server.rollbar.handlers.mocha.test.mjs +253 -0
  155. package/test/server.rollbar.logging.mocha.test.mjs +326 -0
  156. package/test/server.rollbar.misc.mocha.test.mjs +44 -0
  157. package/test/server.rollbar.test-utils.mjs +57 -0
  158. package/test/server.telemetry.mocha.test.mjs +377 -0
  159. package/test/server.transforms.data.mocha.test.mjs +163 -0
  160. package/test/server.transforms.error.mocha.test.mjs +199 -0
  161. package/test/server.transforms.request.mocha.test.mjs +208 -0
  162. package/test/server.transforms.scrub.mocha.test.mjs +140 -0
  163. package/test/server.transforms.sourcemaps.mocha.test.mjs +122 -0
  164. package/test/server.transforms.test-utils.mjs +62 -0
  165. package/test/server.transport.mocha.test.mjs +269 -0
  166. package/test/telemetry.test.js +178 -38
  167. package/test/tracing/contextManager.test.js +28 -0
  168. package/test/tracing/exporter.toPayload.test.js +400 -0
  169. package/test/tracing/id.test.js +24 -0
  170. package/test/tracing/span.test.js +183 -0
  171. package/test/tracing/spanProcessor.test.js +73 -0
  172. package/test/tracing/tracing.test.js +105 -0
  173. package/test/transforms.test.js +70 -68
  174. package/test/truncation.test.js +57 -55
  175. package/test/utility.test.js +310 -228
  176. package/webpack.config.js +36 -70
  177. package/.eslintignore +0 -7
  178. package/.gitmodules +0 -3
  179. package/test/server.lambda.test.js +0 -177
  180. package/test/server.locals.test.js +0 -841
  181. package/test/server.parser.test.js +0 -72
  182. package/test/server.predicates.test.js +0 -89
  183. package/test/server.rollbar.test.js +0 -676
  184. package/test/server.telemetry.test.js +0 -318
  185. package/test/server.transforms.test.js +0 -1099
  186. package/test/server.transport.test.js +0 -201
package/src/rollbar.js CHANGED
@@ -1,7 +1,7 @@
1
- var RateLimiter = require('./rateLimiter');
2
- var Queue = require('./queue');
3
- var Notifier = require('./notifier');
4
- var _ = require('./utility');
1
+ const RateLimiter = require('./rateLimiter');
2
+ const Queue = require('./queue');
3
+ const Notifier = require('./notifier');
4
+ const _ = require('./utility');
5
5
 
6
6
  /*
7
7
  * Rollbar - the interface to Rollbar
@@ -10,14 +10,17 @@ var _ = require('./utility');
10
10
  * @param api
11
11
  * @param logger
12
12
  */
13
- function Rollbar(options, api, logger, telemeter, platform) {
13
+ function Rollbar(options, api, logger, telemeter, tracing, replayMap, platform) {
14
14
  this.options = _.merge(options);
15
15
  this.logger = logger;
16
16
  Rollbar.rateLimiter.configureGlobal(this.options);
17
17
  Rollbar.rateLimiter.setPlatformOptions(platform, this.options);
18
18
  this.api = api;
19
- this.queue = new Queue(Rollbar.rateLimiter, api, logger, this.options);
19
+ this.queue = new Queue(Rollbar.rateLimiter, api, logger, this.options, replayMap);
20
20
 
21
+ this.tracing = tracing;
22
+
23
+ // Legacy OpenTracing support
21
24
  // This must happen before the Notifier is created
22
25
  var tracer = this.options.tracer || null;
23
26
  if (validateTracer(tracer)) {
@@ -38,7 +41,7 @@ function Rollbar(options, api, logger, telemeter, platform) {
38
41
 
39
42
  var defaultOptions = {
40
43
  maxItems: 0,
41
- itemsPerMinute: 60
44
+ itemsPerMinute: 60,
42
45
  };
43
46
 
44
47
  Rollbar.rateLimiter = new RateLimiter(defaultOptions);
@@ -57,6 +60,7 @@ Rollbar.prototype.configure = function (options, payloadData) {
57
60
 
58
61
  this.options = _.merge(oldOptions, options, payload);
59
62
 
63
+ // Legacy OpenTracing support
60
64
  // This must happen before the Notifier is configured
61
65
  var tracer = this.options.tracer || null;
62
66
  if (validateTracer(tracer)) {
@@ -74,7 +78,7 @@ Rollbar.prototype.configure = function (options, payloadData) {
74
78
  this.global(this.options);
75
79
 
76
80
  if (validateTracer(options.tracer)) {
77
- this.tracer = options.tracer
81
+ this.tracer = options.tracer;
78
82
  }
79
83
 
80
84
  return this;
@@ -150,10 +154,25 @@ Rollbar.prototype._log = function (defaultLevel, item) {
150
154
  return;
151
155
  }
152
156
  try {
153
- this._addTracingInfo(item);
154
157
  item.level = item.level || defaultLevel;
155
- this.telemeter && this.telemeter._captureRollbarItem(item);
156
- item.telemetryEvents = (this.telemeter && this.telemeter.copyEvents()) || [];
158
+
159
+ const replayId = this._replayIdIfTriggered(item);
160
+ this._addTracingAttributes(item, replayId);
161
+
162
+ // Legacy OpenTracing support
163
+ this._addTracingInfo(item);
164
+
165
+ const telemeter = this.telemeter;
166
+ if (telemeter) {
167
+ telemeter._captureRollbarItem(item);
168
+ item.telemetryEvents = telemeter.copyEvents() || [];
169
+
170
+ if (telemeter.telemetrySpan) {
171
+ telemeter.telemetrySpan.end({'rollbar.replay.id': replayId});
172
+ telemeter.telemetrySpan = telemeter.tracing.startSpan('rollbar-telemetry', {});
173
+ }
174
+ }
175
+
157
176
  this.notifier.log(item, callback);
158
177
  } catch (e) {
159
178
  if (callback) {
@@ -163,6 +182,30 @@ Rollbar.prototype._log = function (defaultLevel, item) {
163
182
  }
164
183
  };
165
184
 
185
+ Rollbar.prototype._addTracingAttributes = function (item, replayId) {
186
+ const span = this.tracing?.getSpan();
187
+
188
+ const attributes = [
189
+ {key: 'replay_id', value: replayId},
190
+ {key: 'session_id', value: this.tracing?.sessionId},
191
+ {key: 'span_id', value: span?.spanId},
192
+ {key: 'trace_id', value: span?.traceId},
193
+ ];
194
+ _.addItemAttributes(item.data, attributes);
195
+
196
+ span?.addEvent(
197
+ 'rollbar.occurrence',
198
+ [{key: 'rollbar.occurrence.uuid', value: item.uuid}],
199
+ );
200
+ };
201
+
202
+ Rollbar.prototype._replayIdIfTriggered = function (item) {
203
+ const levels = this.options.recorder?.triggerOptions?.item?.levels || [];
204
+ if (levels.includes(item.level)) {
205
+ return this.tracing?.idGen(8);
206
+ }
207
+ }
208
+
166
209
  Rollbar.prototype._defaultLogLevel = function () {
167
210
  return this.options.logLevel || 'debug';
168
211
  };
@@ -191,8 +234,14 @@ Rollbar.prototype._addTracingInfo = function (item) {
191
234
  span.setTag('rollbar.error_uuid', item.uuid);
192
235
  span.setTag('rollbar.has_error', true);
193
236
  span.setTag('error', true);
194
- span.setTag('rollbar.item_url', `https://rollbar.com/item/uuid/?uuid=${item.uuid}`);
195
- span.setTag('rollbar.occurrence_url', `https://rollbar.com/occurrence/uuid/?uuid=${item.uuid}`);
237
+ span.setTag(
238
+ 'rollbar.item_url',
239
+ `https://rollbar.com/item/uuid/?uuid=${item.uuid}`,
240
+ );
241
+ span.setTag(
242
+ 'rollbar.occurrence_url',
243
+ `https://rollbar.com/occurrence/uuid/?uuid=${item.uuid}`,
244
+ );
196
245
 
197
246
  // add span ID & trace ID to occurrence
198
247
  var opentracingSpanId = span.context().toSpanId();
@@ -204,12 +253,12 @@ Rollbar.prototype._addTracingInfo = function (item) {
204
253
  } else {
205
254
  item.custom = {
206
255
  opentracing_span_id: opentracingSpanId,
207
- opentracing_trace_id: opentracingTraceId
256
+ opentracing_trace_id: opentracingTraceId,
208
257
  };
209
258
  }
210
259
  }
211
260
  }
212
- }
261
+ };
213
262
 
214
263
  function generateItemHash(item) {
215
264
  var message = item.message || '';
@@ -260,12 +309,14 @@ function validateSpan(span) {
260
309
 
261
310
  var spanContext = span.context();
262
311
 
263
- if (!spanContext
264
- || !spanContext.toSpanId
265
- || !spanContext.toTraceId
266
- || typeof spanContext.toSpanId !== 'function'
267
- || typeof spanContext.toTraceId !== 'function') {
268
- return false
312
+ if (
313
+ !spanContext ||
314
+ !spanContext.toSpanId ||
315
+ !spanContext.toTraceId ||
316
+ typeof spanContext.toSpanId !== 'function' ||
317
+ typeof spanContext.toTraceId !== 'function'
318
+ ) {
319
+ return false;
269
320
  }
270
321
 
271
322
  return true;
package/src/scrub.js CHANGED
@@ -79,7 +79,6 @@ function _getScrubFieldRegexs(scrubFields) {
79
79
  return ret;
80
80
  }
81
81
 
82
-
83
82
  function _getScrubQueryParamRegexs(scrubFields) {
84
83
  var ret = [];
85
84
  var pat;
@@ -15,8 +15,8 @@ var DEFAULT_OPTIONS = {
15
15
  uncaughtOnly: true,
16
16
  depth: 1,
17
17
  maxProperties: 30,
18
- maxArray: 5
19
- }
18
+ maxArray: 5,
19
+ };
20
20
 
21
21
  function Locals(options, logger) {
22
22
  if (!(this instanceof Locals)) {
@@ -31,7 +31,7 @@ function Locals(options, logger) {
31
31
  this.initSession();
32
32
  }
33
33
 
34
- Locals.prototype.initSession = function() {
34
+ Locals.prototype.initSession = function () {
35
35
  if (Locals.session) {
36
36
  this.disconnectSession();
37
37
  }
@@ -62,33 +62,39 @@ Locals.prototype.initSession = function() {
62
62
  self.initialized = true;
63
63
  updatePauseState(self.options, self.logger);
64
64
  });
65
- }
65
+ };
66
66
 
67
- Locals.prototype.disconnectSession = function() {
67
+ Locals.prototype.disconnectSession = function () {
68
68
  if (Locals.session) {
69
69
  updatePauseState({ enabled: false }, this.logger);
70
70
  Locals.session.disconnect();
71
71
  Locals.session = null;
72
72
  }
73
- }
73
+ };
74
74
 
75
- Locals.prototype.updateOptions = function(options) {
76
- var pauseStateChanged = this.options.enabled != options.enabled || this.options.uncaughtOnly != options.uncaughtOnly;
75
+ Locals.prototype.updateOptions = function (options) {
76
+ var pauseStateChanged =
77
+ this.options.enabled != options.enabled ||
78
+ this.options.uncaughtOnly != options.uncaughtOnly;
77
79
 
78
80
  this.options = _.merge(this.options, options);
79
81
 
80
82
  if (this.initialized && pauseStateChanged) {
81
83
  updatePauseState(this.options, this.logger);
82
84
  }
83
- }
85
+ };
84
86
 
85
87
  function updatePauseState(options, logger) {
86
88
  var state = pauseStateFromOptions(options);
87
- Locals.session.post('Debugger.setPauseOnExceptions', { state: state}, (err, _result) => {
88
- if (err) {
89
- logger.error('error in setPauseOnExceptions', err);
90
- }
91
- });
89
+ Locals.session.post(
90
+ 'Debugger.setPauseOnExceptions',
91
+ { state: state },
92
+ (err, _result) => {
93
+ if (err) {
94
+ logger.error('error in setPauseOnExceptions', err);
95
+ }
96
+ },
97
+ );
92
98
  }
93
99
 
94
100
  function pauseStateFromOptions(options) {
@@ -103,11 +109,11 @@ function pauseStateFromOptions(options) {
103
109
  }
104
110
  }
105
111
 
106
- Locals.prototype.currentLocalsMap = function() {
112
+ Locals.prototype.currentLocalsMap = function () {
107
113
  return new Map(Locals.currentErrors);
108
- }
114
+ };
109
115
 
110
- Locals.prototype.mergeLocals = function(localsMap, stack, key, callback) {
116
+ Locals.prototype.mergeLocals = function (localsMap, stack, key, callback) {
111
117
  var matchedFrames;
112
118
 
113
119
  try {
@@ -124,22 +130,26 @@ Locals.prototype.mergeLocals = function(localsMap, stack, key, callback) {
124
130
  }
125
131
 
126
132
  getLocalScopesForFrames(matchedFrames, this.options, callback);
127
- }
133
+ };
128
134
 
129
135
  // Finds frames in localParams that match file and line locations in stack.
130
136
  function matchFrames(localParams, stack) {
131
137
  var matchedFrames = [];
132
- var localIndex = 0, stackIndex = 0;
138
+ var localIndex = 0,
139
+ stackIndex = 0;
133
140
  var stackLength = stack.length;
134
141
  var callFrames = localParams.callFrames;
135
142
  var callFramesLength = callFrames.length;
136
143
 
137
144
  for (; stackIndex < stackLength; stackIndex++) {
138
145
  while (localIndex < callFramesLength) {
139
- if (firstFrame(localIndex, stackIndex) || matchedFrame(callFrames[localIndex], stack[stackIndex])) {
146
+ if (
147
+ firstFrame(localIndex, stackIndex) ||
148
+ matchedFrame(callFrames[localIndex], stack[stackIndex])
149
+ ) {
140
150
  matchedFrames.push({
141
151
  stackLocation: stack[stackIndex],
142
- callFrame: callFrames[localIndex]
152
+ callFrame: callFrames[localIndex],
143
153
  });
144
154
  localIndex++;
145
155
  break;
@@ -165,32 +175,38 @@ function matchedFrame(callFrame, stackLocation) {
165
175
 
166
176
  // Node.js prefixes filename some URLs with 'file:///' in Debugger.callFrame,
167
177
  // but with only '/' in the error.stack string. Remove the prefix to facilitate a match.
168
- var callFrameUrl = callFrame.url.replace(/file:\/\//,'');
178
+ var callFrameUrl = callFrame.url.replace(/file:\/\//, '');
169
179
 
170
180
  // lineNumber is zero indexed, so offset it.
171
181
  var callFrameLine = callFrame.location.lineNumber + 1;
172
182
  var callFrameColumn = callFrame.location.columnNumber;
173
183
 
174
- return callFrameUrl === position.source &&
184
+ return (
185
+ callFrameUrl === position.source &&
175
186
  callFrameLine === position.line &&
176
- callFrameColumn === position.column;
187
+ callFrameColumn === position.column
188
+ );
177
189
  }
178
190
 
179
191
  function getLocalScopesForFrames(matchedFrames, options, callback) {
180
- async.each(matchedFrames, getLocalScopeForFrame.bind({ options: options }), callback);
192
+ async.each(
193
+ matchedFrames,
194
+ getLocalScopeForFrame.bind({ options: options }),
195
+ callback,
196
+ );
181
197
  }
182
198
 
183
199
  function getLocalScopeForFrame(matchedFrame, callback) {
184
200
  var options = this.options;
185
201
  var scopes = matchedFrame.callFrame.scopeChain;
186
202
 
187
- var scope = scopes.find(scope => scope.type === 'local');
203
+ var scope = scopes.find((scope) => scope.type === 'local');
188
204
 
189
205
  if (!scope) {
190
206
  return callback(null); // Do nothing return success.
191
207
  }
192
208
 
193
- getProperties(scope.object.objectId, function(err, response){
209
+ getProperties(scope.object.objectId, function (err, response) {
194
210
  if (err) {
195
211
  return callback(err);
196
212
  }
@@ -200,8 +216,8 @@ function getLocalScopeForFrame(matchedFrame, callback) {
200
216
  var localsContext = {
201
217
  localsObject: matchedFrame.stackLocation.locals,
202
218
  options: options,
203
- depth: options.depth
204
- }
219
+ depth: options.depth,
220
+ };
205
221
  async.each(locals, getLocalValue.bind(localsContext), callback);
206
222
  });
207
223
  }
@@ -234,11 +250,21 @@ function getLocalValue(local, callback) {
234
250
  }
235
251
 
236
252
  switch (local.value.type) {
237
- case 'undefined': cb(null, 'undefined'); break;
238
- case 'object': getObjectValue(local, options, depth, cb); break;
239
- case 'function': cb(null, getObjectType(local)); break;
240
- case 'symbol': cb(null, getSymbolValue(local)); break;
241
- default: cb(null, local.value.value); break;
253
+ case 'undefined':
254
+ cb(null, 'undefined');
255
+ break;
256
+ case 'object':
257
+ getObjectValue(local, options, depth, cb);
258
+ break;
259
+ case 'function':
260
+ cb(null, getObjectType(local));
261
+ break;
262
+ case 'symbol':
263
+ cb(null, getSymbolValue(local));
264
+ break;
265
+ default:
266
+ cb(null, local.value.value);
267
+ break;
242
268
  }
243
269
  }
244
270
 
@@ -266,7 +292,7 @@ function getObjectValue(local, options, depth, callback) {
266
292
  return callback(null, getObjectType(local));
267
293
  }
268
294
 
269
- getProperties(local.value.objectId, function(err, response){
295
+ getProperties(local.value.objectId, function (err, response) {
270
296
  if (err) {
271
297
  return callback(err);
272
298
  }
@@ -277,13 +303,13 @@ function getObjectValue(local, options, depth, callback) {
277
303
  var localsContext = {
278
304
  localsObject: isArray ? [] : {},
279
305
  options: options,
280
- depth: depth - 1
281
- }
306
+ depth: depth - 1,
307
+ };
282
308
 
283
309
  // For arrays, use eachSeries to ensure order is preserved.
284
310
  // Otherwise, use each for faster completion.
285
311
  var iterator = isArray ? async.eachSeries : async.each;
286
- iterator(properties, getLocalValue.bind(localsContext), function(error){
312
+ iterator(properties, getLocalValue.bind(localsContext), function (error) {
287
313
  if (error) {
288
314
  return callback(error);
289
315
  }
@@ -294,7 +320,11 @@ function getObjectValue(local, options, depth, callback) {
294
320
  }
295
321
 
296
322
  function getProperties(objectId, callback) {
297
- Locals.session.post('Runtime.getProperties', { objectId : objectId, ownProperties: true }, callback);
323
+ Locals.session.post(
324
+ 'Runtime.getProperties',
325
+ { objectId: objectId, ownProperties: true },
326
+ callback,
327
+ );
298
328
  }
299
329
 
300
330
  module.exports = Locals;
@@ -4,20 +4,20 @@ var verbose = true;
4
4
 
5
5
  var logger = {
6
6
  /* eslint-disable no-console */
7
- log: function() {
7
+ log: function () {
8
8
  if (verbose) {
9
9
  console.log.apply(console, arguments);
10
10
  }
11
11
  },
12
- error: function() {
12
+ error: function () {
13
13
  if (verbose) {
14
14
  console.error.apply(console, arguments);
15
15
  }
16
16
  },
17
17
  /* eslint-enable no-console */
18
- setVerbose: function(val) {
18
+ setVerbose: function (val) {
19
19
  verbose = val;
20
- }
20
+ },
21
21
  };
22
22
 
23
23
  module.exports = logger;
@@ -14,19 +14,16 @@ var tracePattern =
14
14
  var jadeTracePattern = /^\s*at .+ \(.+ (at[^)]+\))\)$/;
15
15
  var jadeFramePattern = /^\s*(>?) [0-9]+\|(\s*.+)$/m;
16
16
 
17
-
18
- var cache = new lru({max: 100});
17
+ var cache = new lru({ max: 100 });
19
18
  var pendingReads = {};
20
19
 
21
20
  exports.cache = cache;
22
21
  exports.pendingReads = pendingReads;
23
22
 
24
-
25
23
  /*
26
24
  * Internal
27
25
  */
28
26
 
29
-
30
27
  function getMultipleErrors(errors) {
31
28
  var errArray, key;
32
29
 
@@ -52,10 +49,19 @@ function getMultipleErrors(errors) {
52
49
  return errArray;
53
50
  }
54
51
 
55
-
56
52
  function parseJadeDebugFrame(body) {
57
- var lines, lineNumSep, filename, lineno, numLines, msg, i,
58
- contextLine, preContext, postContext, line, jadeMatch;
53
+ var lines,
54
+ lineNumSep,
55
+ filename,
56
+ lineno,
57
+ numLines,
58
+ msg,
59
+ i,
60
+ contextLine,
61
+ preContext,
62
+ postContext,
63
+ line,
64
+ jadeMatch;
59
65
 
60
66
  // Given a Jade exception body, return a frame object
61
67
  lines = body.split('\n');
@@ -90,7 +96,10 @@ function parseJadeDebugFrame(body) {
90
96
  }
91
97
 
92
98
  preContext = preContext.slice(0, Math.min(preContext.length, linesOfContext));
93
- postContext = postContext.slice(0, Math.min(postContext.length, linesOfContext));
99
+ postContext = postContext.slice(
100
+ 0,
101
+ Math.min(postContext.length, linesOfContext),
102
+ );
94
103
 
95
104
  return {
96
105
  frame: {
@@ -100,29 +109,32 @@ function parseJadeDebugFrame(body) {
100
109
  code: contextLine,
101
110
  context: {
102
111
  pre: preContext,
103
- post: postContext
104
- }
112
+ post: postContext,
113
+ },
105
114
  },
106
- message: msg
115
+ message: msg,
107
116
  };
108
117
  }
109
118
 
110
-
111
119
  function extractContextLines(frame, fileLines) {
112
120
  frame.code = fileLines[frame.lineno - 1];
113
121
  frame.context = {
114
- pre: fileLines.slice(Math.max(0, frame.lineno - (linesOfContext + 1)), frame.lineno - 1),
115
- post: fileLines.slice(frame.lineno, frame.lineno + linesOfContext)
122
+ pre: fileLines.slice(
123
+ Math.max(0, frame.lineno - (linesOfContext + 1)),
124
+ frame.lineno - 1,
125
+ ),
126
+ post: fileLines.slice(frame.lineno, frame.lineno + linesOfContext),
116
127
  };
117
128
  }
118
129
 
119
130
  function mapPosition(position, diagnostic) {
120
- return stackTrace.mapSourcePosition({
131
+ return stackTrace.mapSourcePosition(
132
+ {
121
133
  source: position.source,
122
134
  line: position.line,
123
- column: position.column
135
+ column: position.column,
124
136
  },
125
- diagnostic
137
+ diagnostic,
126
138
  );
127
139
  }
128
140
 
@@ -144,7 +156,7 @@ function parseFrameLine(line, callback) {
144
156
  var runtimePosition = {
145
157
  source: data[1],
146
158
  line: Math.floor(data[2]),
147
- column: Math.floor(data[3]) - 1
159
+ column: Math.floor(data[3]) - 1,
148
160
  };
149
161
  if (this.useSourceMaps) {
150
162
  position = mapPosition(runtimePosition, this.diagnostic);
@@ -157,7 +169,7 @@ function parseFrameLine(line, callback) {
157
169
  filename: position.source,
158
170
  lineno: position.line,
159
171
  colno: position.column,
160
- runtimePosition: runtimePosition // Used to match frames for locals
172
+ runtimePosition: runtimePosition, // Used to match frames for locals
161
173
  };
162
174
 
163
175
  // For coffeescript, lineno and colno refer to the .coffee positions
@@ -173,7 +185,6 @@ function parseFrameLine(line, callback) {
173
185
  callback(null, frame);
174
186
  }
175
187
 
176
-
177
188
  function shouldReadFrameFile(frameFilename, callback) {
178
189
  var isValidFilename, isCached, isPending;
179
190
 
@@ -184,7 +195,6 @@ function shouldReadFrameFile(frameFilename, callback) {
184
195
  callback(null, isValidFilename && !isCached && !isPending);
185
196
  }
186
197
 
187
-
188
198
  function readFileLines(filename, callback) {
189
199
  try {
190
200
  fs.readFile(filename, function (err, fileData) {
@@ -210,7 +220,6 @@ function checkFileExists(filename, callback) {
210
220
  });
211
221
  }
212
222
 
213
-
214
223
  function gatherContexts(frames, callback) {
215
224
  var frameFilenames = [];
216
225
 
@@ -280,7 +289,6 @@ function gatherContexts(frames, callback) {
280
289
  });
281
290
  });
282
291
  });
283
-
284
292
  });
285
293
  }
286
294
 
@@ -288,7 +296,6 @@ function gatherContexts(frames, callback) {
288
296
  * Public API
289
297
  */
290
298
 
291
-
292
299
  exports.parseException = function (exc, options, item, callback) {
293
300
  var multipleErrs = getMultipleErrors(exc.errors);
294
301
 
@@ -299,13 +306,13 @@ exports.parseException = function (exc, options, item, callback) {
299
306
  logger.error('could not parse exception, err: ' + err);
300
307
  return callback(err);
301
308
  }
302
- message = String(exc.message || '<no message>') ;
309
+ message = String(exc.message || '<no message>');
303
310
  clss = String(exc.name || '<unknown>');
304
311
 
305
312
  ret = {
306
313
  class: clss,
307
314
  message: message,
308
- frames: stack
315
+ frames: stack,
309
316
  };
310
317
 
311
318
  if (multipleErrs && multipleErrs.length) {
@@ -313,7 +320,7 @@ exports.parseException = function (exc, options, item, callback) {
313
320
  ret = {
314
321
  class: clss,
315
322
  message: String(firstErr.message || '<no message>'),
316
- frames: stack
323
+ frames: stack,
317
324
  };
318
325
  }
319
326
 
@@ -325,25 +332,30 @@ exports.parseException = function (exc, options, item, callback) {
325
332
  }
326
333
 
327
334
  if (item.localsMap) {
328
- item.notifier.locals.mergeLocals(item.localsMap, stack, exc.stack, function (err) {
329
- if (err) {
330
- logger.error('could not parse locals, err: ' + err);
335
+ item.notifier.locals.mergeLocals(
336
+ item.localsMap,
337
+ stack,
338
+ exc.stack,
339
+ function (err) {
340
+ if (err) {
341
+ logger.error('could not parse locals, err: ' + err);
331
342
 
332
- // Don't reject the occurrence, record the error instead.
333
- item.diagnostic['error parsing locals'] = err;
334
- }
343
+ // Don't reject the occurrence, record the error instead.
344
+ item.diagnostic['error parsing locals'] = err;
345
+ }
335
346
 
336
- return callback(null, ret);
337
- });
347
+ return callback(null, ret);
348
+ },
349
+ );
338
350
  } else {
339
351
  return callback(null, ret);
340
352
  }
341
353
  });
342
354
  };
343
355
 
344
-
345
356
  exports.parseStack = function (stack, options, item, callback) {
346
- var lines, _stack = stack;
357
+ var lines,
358
+ _stack = stack;
347
359
 
348
360
  // Some JS frameworks (e.g. Meteor) might bury the stack property
349
361
  while (typeof _stack === 'object') {
@@ -359,14 +371,27 @@ exports.parseStack = function (stack, options, item, callback) {
359
371
  }
360
372
 
361
373
  // Parse out all of the frame and filename info
362
- async.map(lines, parseFrameLine.bind({ useSourceMaps: options.nodeSourceMaps, diagnostic: item.diagnostic }), function (err, frames) {
363
- if (err) {
364
- return callback(err);
365
- }
366
- frames.reverse();
367
- async.filter(frames, function (frame, callback) { callback(null, !!frame); }, function (err, results) {
368
- if (err) return callback(err);
369
- gatherContexts(results, callback);
370
- });
371
- });
374
+ async.map(
375
+ lines,
376
+ parseFrameLine.bind({
377
+ useSourceMaps: options.nodeSourceMaps,
378
+ diagnostic: item.diagnostic,
379
+ }),
380
+ function (err, frames) {
381
+ if (err) {
382
+ return callback(err);
383
+ }
384
+ frames.reverse();
385
+ async.filter(
386
+ frames,
387
+ function (frame, callback) {
388
+ callback(null, !!frame);
389
+ },
390
+ function (err, results) {
391
+ if (err) return callback(err);
392
+ gatherContexts(results, callback);
393
+ },
394
+ );
395
+ },
396
+ );
372
397
  };