Skip to content

Commit 6dc5dcb

Browse files
committed
captureMessage can attach stack trace via stacktrace: true
1 parent a8c717f commit 6dc5dcb

File tree

1 file changed

+49
-10
lines changed

1 file changed

+49
-10
lines changed

src/raven.js

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,9 @@ Raven.prototype = {
278278
return func.apply(this, args);
279279
} catch(e) {
280280
self._ignoreNextOnError();
281-
self.captureException(e, options, 1);
281+
self.captureException(e, objectMerge({
282+
trimTailFrames: 1
283+
}, options));
282284
throw e;
283285
}
284286
}
@@ -323,11 +325,14 @@ Raven.prototype = {
323325
* @param {object} options A specific set of options for this error [optional]
324326
* @return {Raven}
325327
*/
326-
captureException: function(ex, options, skipframes) {
327-
skipframes = skipframes || 0;
328-
328+
captureException: function(ex, options) {
329329
// If not an Error is passed through, recall as a message instead
330-
if (!isError(ex)) return this.captureMessage(ex, options, skipframes + 1);
330+
if (!isError(ex)) {
331+
return this.captureMessage(ex, objectMerge({
332+
trimHeadFrames: 1,
333+
stacktrace: true // if we fall back to captureMessage, default to attempting a new trace
334+
}, options));
335+
}
331336

332337
// Store the raw exception object for potential debugging and introspection
333338
this._lastCapturedException = ex;
@@ -339,7 +344,7 @@ Raven.prototype = {
339344
// report on.
340345
try {
341346
var stack = TraceKit.computeStackTrace(ex);
342-
this._handleStackInfo(stack, options, skipframes);
347+
this._handleStackInfo(stack, options);
343348
} catch(ex1) {
344349
if(ex !== ex1) {
345350
throw ex1;
@@ -356,7 +361,36 @@ Raven.prototype = {
356361
* @param {object} options A specific set of options for this message [optional]
357362
* @return {Raven}
358363
*/
359-
captureMessage: function(msg, options, skipframes) {
364+
captureMessage: function(msg, options) {
365+
if (options.stacktrace) {
366+
var ex;
367+
// create a stack trace from this point; just trim
368+
// off extra frames so they don't include this function call (or
369+
// earlier Raven.js library fn calls)
370+
try {
371+
throw new Error(msg);
372+
} catch (ex1) {
373+
ex = ex1;
374+
}
375+
376+
// null exception name so `Error` isn't prefixed to msg
377+
ex.name = null;
378+
379+
options = objectMerge({
380+
// fingerprint on msg, not stack trace
381+
// NOTE: need also to do this because stack could include Raven.wrap,
382+
// which may create inconsistent traces if only using window.onerror
383+
fingerprint: msg,
384+
trimTailFrames: (options.trimHeadFrames || 0) + 1
385+
}, options);
386+
387+
// infinite loop if ex *somehow* returns false for isError
388+
// is that possible when it is result of try/catch?
389+
this.captureException(ex, options);
390+
391+
return this;
392+
}
393+
360394
// config() automagically converts ignoreErrors from a list to a RegExp so we need to test for an
361395
// early call; we'll error on the side of logging anything called before configuration since it's
362396
// probably something you should see:
@@ -1066,7 +1100,7 @@ Raven.prototype = {
10661100
}
10671101
},
10681102

1069-
_handleStackInfo: function(stackInfo, options, skipframes) {
1103+
_handleStackInfo: function(stackInfo, options) {
10701104
var self = this;
10711105
var frames = [];
10721106

@@ -1078,8 +1112,13 @@ Raven.prototype = {
10781112
}
10791113
});
10801114

1081-
if (skipframes) {
1082-
frames = frames.slice(0, skipframes);
1115+
// e.g. frames captured via captureMessage throw
1116+
if (options.trimHeadFrames) {
1117+
frames = frames.slice(options.trimHeadFrames);
1118+
}
1119+
// e.g. try/catch (wrapper) frames
1120+
if (options.trimTailFrames) {
1121+
frames = frames.slice(0, options.trimTailFrames);
10831122
}
10841123
}
10851124

0 commit comments

Comments
 (0)