Skip to content

Commit 407848e

Browse files
committed
captureMessage can attach stack trace via stacktrace: true
1 parent 99608a6 commit 407848e

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
@@ -257,7 +257,9 @@ Raven.prototype = {
257257
return func.apply(this, args);
258258
} catch(e) {
259259
self._ignoreNextOnError();
260-
self.captureException(e, options, 1);
260+
self.captureException(e, objectMerge({
261+
trimTailFrames: 1
262+
}, options));
261263
throw e;
262264
}
263265
}
@@ -302,11 +304,14 @@ Raven.prototype = {
302304
* @param {object} options A specific set of options for this error [optional]
303305
* @return {Raven}
304306
*/
305-
captureException: function(ex, options, skipframes) {
306-
skipframes = skipframes || 0;
307-
307+
captureException: function(ex, options) {
308308
// If not an Error is passed through, recall as a message instead
309-
if (!isError(ex)) return this.captureMessage(ex, options, skipframes + 1);
309+
if (!isError(ex)) {
310+
return this.captureMessage(ex, objectMerge({
311+
trimHeadFrames: 1,
312+
stacktrace: true // if we fall back to captureMessage, default to attempting a new trace
313+
}, options));
314+
}
310315

311316
// Store the raw exception object for potential debugging and introspection
312317
this._lastCapturedException = ex;
@@ -318,7 +323,7 @@ Raven.prototype = {
318323
// report on.
319324
try {
320325
var stack = TraceKit.computeStackTrace(ex);
321-
this._handleStackInfo(stack, options, skipframes);
326+
this._handleStackInfo(stack, options);
322327
} catch(ex1) {
323328
if(ex !== ex1) {
324329
throw ex1;
@@ -335,7 +340,36 @@ Raven.prototype = {
335340
* @param {object} options A specific set of options for this message [optional]
336341
* @return {Raven}
337342
*/
338-
captureMessage: function(msg, options, skipframes) {
343+
captureMessage: function(msg, options) {
344+
if (options.stacktrace) {
345+
var ex;
346+
// create a stack trace from this point; just trim
347+
// off extra frames so they don't include this function call (or
348+
// earlier Raven.js library fn calls)
349+
try {
350+
throw new Error(msg);
351+
} catch (ex1) {
352+
ex = ex1;
353+
}
354+
355+
// null exception name so `Error` isn't prefixed to msg
356+
ex.name = null;
357+
358+
options = objectMerge({
359+
// fingerprint on msg, not stack trace
360+
// NOTE: need also to do this because stack could include Raven.wrap,
361+
// which may create inconsistent traces if only using window.onerror
362+
fingerprint: msg,
363+
trimTailFrames: (options.trimHeadFrames || 0) + 1
364+
}, options);
365+
366+
// infinite loop if ex *somehow* returns false for isError
367+
// is that possible when it is result of try/catch?
368+
this.captureException(ex, options);
369+
370+
return this;
371+
}
372+
339373
// config() automagically converts ignoreErrors from a list to a RegExp so we need to test for an
340374
// early call; we'll error on the side of logging anything called before configuration since it's
341375
// probably something you should see:
@@ -1012,7 +1046,7 @@ Raven.prototype = {
10121046
}
10131047
},
10141048

1015-
_handleStackInfo: function(stackInfo, options, skipframes) {
1049+
_handleStackInfo: function(stackInfo, options) {
10161050
var self = this;
10171051
var frames = [];
10181052

@@ -1024,8 +1058,13 @@ Raven.prototype = {
10241058
}
10251059
});
10261060

1027-
if (skipframes) {
1028-
frames = frames.slice(0, skipframes);
1061+
// e.g. frames captured via captureMessage throw
1062+
if (options.trimHeadFrames) {
1063+
frames = frames.slice(options.trimHeadFrames);
1064+
}
1065+
// e.g. try/catch (wrapper) frames
1066+
if (options.trimTailFrames) {
1067+
frames = frames.slice(0, options.trimTailFrames);
10291068
}
10301069
}
10311070

0 commit comments

Comments
 (0)