@@ -19,51 +19,45 @@ export class Dedupe implements Integration {
1919 */
2020 public install ( ) : void {
2121 getCurrentHub ( ) . configureScope ( ( scope : Scope ) => {
22- scope . addEventProcessor ( async ( event : SentryEvent ) => {
22+ scope . addEventProcessor ( async ( currentEvent : SentryEvent ) => {
2323 // Juuust in case something goes wrong
2424 try {
25- if ( this . shouldDropEvent ( event ) ) {
25+ if ( this . shouldDropEvent ( currentEvent , this . previousEvent ) ) {
2626 return null ;
2727 }
2828 } catch ( _oO ) {
29- return ( this . previousEvent = event ) ;
29+ return ( this . previousEvent = currentEvent ) ;
3030 }
3131
32- return ( this . previousEvent = event ) ;
32+ return ( this . previousEvent = currentEvent ) ;
3333 } ) ;
3434 } ) ;
3535 }
3636
3737 /** JSDoc */
38- public shouldDropEvent ( event : SentryEvent ) : boolean {
39- if ( ! this . previousEvent ) {
38+ public shouldDropEvent ( currentEvent : SentryEvent , previousEvent ? : SentryEvent ) : boolean {
39+ if ( ! previousEvent ) {
4040 return false ;
4141 }
4242
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+ }
4947
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+ }
5651
57- if ( this . isSameStacktrace ( event ) ) {
5852 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 } ` ,
6054 ) ;
6155 return true ;
6256 }
6357
64- if ( this . isSameFingerprint ( event ) ) {
58+ if ( this . isSameException ( currentEvent , previousEvent ) ) {
6559 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 } ` ,
6761 ) ;
6862 return true ;
6963 }
@@ -72,11 +66,22 @@ export class Dedupe implements Integration {
7266 }
7367
7468 /** 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 ) ) {
7780 return false ;
7881 }
79- return ! ! ( event . message && this . previousEvent . message && event . message === this . previousEvent . message ) ;
82+
83+ // Otherwise, compare the two
84+ return currentMessage === previousMessage ;
8085 }
8186
8287 /** JSDoc */
@@ -98,18 +103,29 @@ export class Dedupe implements Integration {
98103 }
99104
100105 /** 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 ) ) {
103117 return false ;
104118 }
105119
106- const previousFrames = this . getFramesFromEvent ( this . previousEvent ) ;
107- const currentFrames = this . getFramesFromEvent ( event ) ;
120+ currentFrames = currentFrames as StackFrame [ ] ;
121+ previousFrames = previousFrames as StackFrame [ ] ;
108122
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 ) {
110125 return false ;
111126 }
112127
128+ // Otherwise, compare the two
113129 for ( let i = 0 ; i < previousFrames . length ; i ++ ) {
114130 const frameA = previousFrames [ i ] ;
115131 const frameB = currentFrames [ i ] ;
@@ -133,13 +149,9 @@ export class Dedupe implements Integration {
133149 }
134150
135151 /** 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 ) ;
143155
144156 if ( ! previousException || ! currentException ) {
145157 return false ;
@@ -149,16 +161,32 @@ export class Dedupe implements Integration {
149161 return false ;
150162 }
151163
152- return this . isSameStacktrace ( event ) ;
164+ return this . isSameStacktrace ( currentEvent , previousEvent ) ;
153165 }
154166
155167 /** 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 ) ) {
158179 return false ;
159180 }
160181
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+ }
163191 }
164192}
0 commit comments