Skip to content

Commit bdaf4a5

Browse files
committed
Ignore duplicate payloads
1 parent 76f13b5 commit bdaf4a5

File tree

3 files changed

+63
-6
lines changed

3 files changed

+63
-6
lines changed

example/index.html

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,9 @@
1515
whitelistUrls: [
1616
/localhost/,
1717
/127\.0\.0\.1/
18-
],
19-
dataCallback: function(data) {
20-
console.log(data);
21-
return data;
22-
}
18+
]
2319
}).install();
20+
Raven.debug = true;
2421

2522
Raven.setUserContext({
2623

src/raven.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ function Raven() {
3131
this._hasDocument = !isUndefined(_document);
3232
this._hasNavigator = !isUndefined(_navigator);
3333
this._lastCapturedException = null;
34+
this._lastData = null;
3435
this._lastEventId = null;
3536
this._globalServer = null;
3637
this._globalKey = null;
@@ -1334,6 +1335,55 @@ Raven.prototype = {
13341335
return this._backoffDuration && now() - this._backoffStart < this._backoffDuration;
13351336
},
13361337

1338+
/**
1339+
* Returns true if the in-process data payload matches the signature
1340+
* of the previously-sent data
1341+
*
1342+
* NOTE: This has to be done at this level because TraceKit can generate
1343+
* data from window.onerror WITHOUT an exception object (IE8, IE9,
1344+
* other old browsers). This can take the form of an "exception"
1345+
* data object with a single frame (derived from the onerror args).
1346+
*/
1347+
_isRepeatData: function (current) {
1348+
var last = this._lastData;
1349+
1350+
if (!last ||
1351+
current.message !== last.message ||
1352+
current.culprit !== last.culprit)
1353+
return false;
1354+
1355+
// If there's no stacktrace, at this point we consider
1356+
// them the same event (e.g. captureMessage)
1357+
if (!(current.exception && last.exception))
1358+
return true;
1359+
1360+
var currentException = current.exception.values[0];
1361+
var lastException = last.exception.values[0];
1362+
1363+
if (currentException.type !== lastException.type ||
1364+
currentException.value !== lastException.value)
1365+
return false;
1366+
1367+
var currentFrames = currentException.stacktrace;
1368+
var lastFrames = lastException.stacktrace;
1369+
1370+
if (currentFrames.length !== lastFrames.length)
1371+
return false;
1372+
1373+
// Iterate through every frame; bail out if anything differs
1374+
var a, b;
1375+
for (var i = 0; i < currentFrames.length; i++) {
1376+
a = currentFrames[i];
1377+
b = lastFrames[i];
1378+
if (a.filename !== b.filename ||
1379+
a.lineno !== b.lineno ||
1380+
a.colno !== b.colno ||
1381+
a['function'] !== b['function'])
1382+
return false;
1383+
}
1384+
return true;
1385+
},
1386+
13371387
_setBackoffState: function(request) {
13381388
// If we are already in a backoff state, don't change anything
13391389
if (this._shouldBackoff()) {
@@ -1460,6 +1510,14 @@ Raven.prototype = {
14601510
// Try and clean up the packet before sending by truncating long values
14611511
data = this._trimPacket(data);
14621512

1513+
if (!this._globalOptions.allowDuplicates && this._isRepeatData(data)) {
1514+
this._logDebug('warn', 'Raven dropped repeat event: ', data);
1515+
return;
1516+
}
1517+
1518+
// Store outbound payload after trim
1519+
this._lastData = data;
1520+
14631521
this._logDebug('debug', 'Raven about to send:', data);
14641522

14651523
var auth = {

test/raven.test.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ if (typeof window.console === 'undefined') {
2626
var SENTRY_DSN = 'http://[email protected]:80/2';
2727

2828
function setupRaven() {
29-
Raven.config(SENTRY_DSN);
29+
Raven.config(SENTRY_DSN, {
30+
allowDuplicates: true
31+
});
3032
}
3133

3234
var Raven;

0 commit comments

Comments
 (0)