Skip to content

Commit c4956d0

Browse files
committed
captureMessage can attach stack trace via stacktrace: true
1 parent 5c42419 commit c4956d0

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
@@ -265,7 +265,9 @@ Raven.prototype = {
265265
return func.apply(this, args);
266266
} catch(e) {
267267
self._ignoreNextOnError();
268-
self.captureException(e, options, 1);
268+
self.captureException(e, objectMerge({
269+
trimTailFrames: 1
270+
}, options));
269271
throw e;
270272
}
271273
}
@@ -310,11 +312,14 @@ Raven.prototype = {
310312
* @param {object} options A specific set of options for this error [optional]
311313
* @return {Raven}
312314
*/
313-
captureException: function(ex, options, skipframes) {
314-
skipframes = skipframes || 0;
315-
315+
captureException: function(ex, options) {
316316
// If not an Error is passed through, recall as a message instead
317-
if (!isError(ex)) return this.captureMessage(ex, options, skipframes + 1);
317+
if (!isError(ex)) {
318+
return this.captureMessage(ex, objectMerge({
319+
trimHeadFrames: 1,
320+
stacktrace: true // if we fall back to captureMessage, default to attempting a new trace
321+
}, options));
322+
}
318323

319324
// Store the raw exception object for potential debugging and introspection
320325
this._lastCapturedException = ex;
@@ -326,7 +331,7 @@ Raven.prototype = {
326331
// report on.
327332
try {
328333
var stack = TraceKit.computeStackTrace(ex);
329-
this._handleStackInfo(stack, options, skipframes);
334+
this._handleStackInfo(stack, options);
330335
} catch(ex1) {
331336
if(ex !== ex1) {
332337
throw ex1;
@@ -343,7 +348,36 @@ Raven.prototype = {
343348
* @param {object} options A specific set of options for this message [optional]
344349
* @return {Raven}
345350
*/
346-
captureMessage: function(msg, options, skipframes) {
351+
captureMessage: function(msg, options) {
352+
if (options.stacktrace) {
353+
var ex;
354+
// create a stack trace from this point; just trim
355+
// off extra frames so they don't include this function call (or
356+
// earlier Raven.js library fn calls)
357+
try {
358+
throw new Error(msg);
359+
} catch (ex1) {
360+
ex = ex1;
361+
}
362+
363+
// null exception name so `Error` isn't prefixed to msg
364+
ex.name = null;
365+
366+
options = objectMerge({
367+
// fingerprint on msg, not stack trace
368+
// NOTE: need also to do this because stack could include Raven.wrap,
369+
// which may create inconsistent traces if only using window.onerror
370+
fingerprint: msg,
371+
trimTailFrames: (options.trimHeadFrames || 0) + 1
372+
}, options);
373+
374+
// infinite loop if ex *somehow* returns false for isError
375+
// is that possible when it is result of try/catch?
376+
this.captureException(ex, options);
377+
378+
return this;
379+
}
380+
347381
// config() automagically converts ignoreErrors from a list to a RegExp so we need to test for an
348382
// early call; we'll error on the side of logging anything called before configuration since it's
349383
// probably something you should see:
@@ -1007,7 +1041,7 @@ Raven.prototype = {
10071041
}
10081042
},
10091043

1010-
_handleStackInfo: function(stackInfo, options, skipframes) {
1044+
_handleStackInfo: function(stackInfo, options) {
10111045
var self = this;
10121046
var frames = [];
10131047

@@ -1019,8 +1053,13 @@ Raven.prototype = {
10191053
}
10201054
});
10211055

1022-
if (skipframes) {
1023-
frames = frames.slice(0, skipframes);
1056+
// e.g. frames captured via captureMessage throw
1057+
if (options.trimHeadFrames) {
1058+
frames = frames.slice(options.trimHeadFrames);
1059+
}
1060+
// e.g. try/catch (wrapper) frames
1061+
if (options.trimTailFrames) {
1062+
frames = frames.slice(0, options.trimTailFrames);
10241063
}
10251064
}
10261065

0 commit comments

Comments
 (0)