@@ -19,51 +19,45 @@ export class Dedupe implements Integration {
19
19
*/
20
20
public install ( ) : void {
21
21
getCurrentHub ( ) . configureScope ( ( scope : Scope ) => {
22
- scope . addEventProcessor ( async ( event : SentryEvent ) => {
22
+ scope . addEventProcessor ( async ( currentEvent : SentryEvent ) => {
23
23
// Juuust in case something goes wrong
24
24
try {
25
- if ( this . shouldDropEvent ( event ) ) {
25
+ if ( this . shouldDropEvent ( currentEvent , this . previousEvent ) ) {
26
26
return null ;
27
27
}
28
28
} catch ( _oO ) {
29
- return ( this . previousEvent = event ) ;
29
+ return ( this . previousEvent = currentEvent ) ;
30
30
}
31
31
32
- return ( this . previousEvent = event ) ;
32
+ return ( this . previousEvent = currentEvent ) ;
33
33
} ) ;
34
34
} ) ;
35
35
}
36
36
37
37
/** JSDoc */
38
- public shouldDropEvent ( event : SentryEvent ) : boolean {
39
- if ( ! this . previousEvent ) {
38
+ public shouldDropEvent ( currentEvent : SentryEvent , previousEvent ? : SentryEvent ) : boolean {
39
+ if ( ! previousEvent ) {
40
40
return false ;
41
41
}
42
42
43
- if ( this . isSameMessage ( event ) ) {
44
- logger . warn (
45
- `Event dropped due to being a duplicate of previous event (same message).\n Event: ${ event . event_id } ` ,
46
- ) ;
47
- return true ;
48
- }
43
+ if ( this . isSameMessage ( currentEvent , previousEvent ) ) {
44
+ if ( ! this . isSameFingerprint ( currentEvent , previousEvent ) ) {
45
+ return false ;
46
+ }
49
47
50
- if ( this . isSameException ( event ) ) {
51
- logger . warn (
52
- `Event dropped due to being a duplicate of previous event (same exception).\n Event: ${ event . event_id } ` ,
53
- ) ;
54
- return true ;
55
- }
48
+ if ( ! this . isSameStacktrace ( currentEvent , previousEvent ) ) {
49
+ return false ;
50
+ }
56
51
57
- if ( this . isSameStacktrace ( event ) ) {
58
52
logger . warn (
59
- `Event dropped due to being a duplicate of previous event (same stacktrace ).\n Event: ${ event . event_id } ` ,
53
+ `Event dropped due to being a duplicate of previous event (same message ).\n Event: ${ currentEvent . event_id } ` ,
60
54
) ;
61
55
return true ;
62
56
}
63
57
64
- if ( this . isSameFingerprint ( event ) ) {
58
+ if ( this . isSameException ( currentEvent , previousEvent ) ) {
65
59
logger . warn (
66
- `Event dropped due to being a duplicate of previous event (same fingerprint ).\n Event: ${ event . event_id } ` ,
60
+ `Event dropped due to being a duplicate of previous event (same exception ).\n Event: ${ currentEvent . event_id } ` ,
67
61
) ;
68
62
return true ;
69
63
}
@@ -72,11 +66,22 @@ export class Dedupe implements Integration {
72
66
}
73
67
74
68
/** JSDoc */
75
- private isSameMessage ( event : SentryEvent ) : boolean {
76
- if ( ! this . previousEvent ) {
69
+ private isSameMessage ( currentEvent : SentryEvent , previousEvent : SentryEvent ) : boolean {
70
+ const currentMessage = currentEvent . message ;
71
+ const previousMessage = previousEvent . message ;
72
+
73
+ // If no event has a message, they were both exceptions, so bail out
74
+ if ( ! currentMessage && ! previousMessage ) {
75
+ return false ;
76
+ }
77
+
78
+ // If only one event has a stacktrace, but not the other one, they are not the same
79
+ if ( ( currentMessage && ! previousMessage ) || ( ! currentMessage && previousMessage ) ) {
77
80
return false ;
78
81
}
79
- return ! ! ( event . message && this . previousEvent . message && event . message === this . previousEvent . message ) ;
82
+
83
+ // Otherwise, compare the two
84
+ return currentMessage === previousMessage ;
80
85
}
81
86
82
87
/** JSDoc */
@@ -98,18 +103,29 @@ export class Dedupe implements Integration {
98
103
}
99
104
100
105
/** JSDoc */
101
- private isSameStacktrace ( event : SentryEvent ) : boolean {
102
- if ( ! this . previousEvent ) {
106
+ private isSameStacktrace ( currentEvent : SentryEvent , previousEvent : SentryEvent ) : boolean {
107
+ let currentFrames = this . getFramesFromEvent ( currentEvent ) ;
108
+ let previousFrames = this . getFramesFromEvent ( previousEvent ) ;
109
+
110
+ // If no event has a fingerprint, they are assumed to be the same
111
+ if ( ! currentFrames && ! previousFrames ) {
112
+ return true ;
113
+ }
114
+
115
+ // If only one event has a stacktrace, but not the other one, they are not the same
116
+ if ( ( currentFrames && ! previousFrames ) || ( ! currentFrames && previousFrames ) ) {
103
117
return false ;
104
118
}
105
119
106
- const previousFrames = this . getFramesFromEvent ( this . previousEvent ) ;
107
- const currentFrames = this . getFramesFromEvent ( event ) ;
120
+ currentFrames = currentFrames as StackFrame [ ] ;
121
+ previousFrames = previousFrames as StackFrame [ ] ;
108
122
109
- if ( ! previousFrames || ! currentFrames || previousFrames . length !== currentFrames . length ) {
123
+ // If number of frames differ, they are not the same
124
+ if ( previousFrames . length !== currentFrames . length ) {
110
125
return false ;
111
126
}
112
127
128
+ // Otherwise, compare the two
113
129
for ( let i = 0 ; i < previousFrames . length ; i ++ ) {
114
130
const frameA = previousFrames [ i ] ;
115
131
const frameB = currentFrames [ i ] ;
@@ -133,13 +149,9 @@ export class Dedupe implements Integration {
133
149
}
134
150
135
151
/** JSDoc */
136
- private isSameException ( event : SentryEvent ) : boolean {
137
- if ( ! this . previousEvent ) {
138
- return false ;
139
- }
140
-
141
- const previousException = this . getExceptionFromEvent ( this . previousEvent ) ;
142
- const currentException = this . getExceptionFromEvent ( event ) ;
152
+ private isSameException ( currentEvent : SentryEvent , previousEvent : SentryEvent ) : boolean {
153
+ const previousException = this . getExceptionFromEvent ( previousEvent ) ;
154
+ const currentException = this . getExceptionFromEvent ( currentEvent ) ;
143
155
144
156
if ( ! previousException || ! currentException ) {
145
157
return false ;
@@ -149,16 +161,32 @@ export class Dedupe implements Integration {
149
161
return false ;
150
162
}
151
163
152
- return this . isSameStacktrace ( event ) ;
164
+ return this . isSameStacktrace ( currentEvent , previousEvent ) ;
153
165
}
154
166
155
167
/** JSDoc */
156
- private isSameFingerprint ( event : SentryEvent ) : boolean {
157
- if ( ! this . previousEvent ) {
168
+ private isSameFingerprint ( currentEvent : SentryEvent , previousEvent : SentryEvent ) : boolean {
169
+ let currentFingerprint = currentEvent . fingerprint ;
170
+ let previousFingerprint = previousEvent . fingerprint ;
171
+
172
+ // If no event has a fingerprint, they are assumed to be the same
173
+ if ( ! currentFingerprint && ! previousFingerprint ) {
174
+ return true ;
175
+ }
176
+
177
+ // If only one event has a fingerprint, but not the other one, they are not the same
178
+ if ( ( currentFingerprint && ! previousFingerprint ) || ( ! currentFingerprint && previousFingerprint ) ) {
158
179
return false ;
159
180
}
160
181
161
- return Boolean ( event . fingerprint && this . previousEvent . fingerprint ) &&
162
- JSON . stringify ( event . fingerprint ) === JSON . stringify ( this . previousEvent . fingerprint )
182
+ currentFingerprint = currentFingerprint as string [ ] ;
183
+ previousFingerprint = previousFingerprint as string [ ] ;
184
+
185
+ // Otherwise, compare the two
186
+ try {
187
+ return ! ! ( currentFingerprint . join ( '' ) === previousFingerprint . join ( '' ) ) ;
188
+ } catch ( _oO ) {
189
+ return false ;
190
+ }
163
191
}
164
192
}
0 commit comments