@@ -4,67 +4,50 @@ import { IEventPlugin } from '../IEventPlugin';
4
4
import { EventPluginContext } from '../EventPluginContext' ;
5
5
import { Utils } from '../../Utils' ;
6
6
7
- const ERROR_KEY : string = '@error' ;
8
- const WINDOW_MILLISECONDS = 2000 ;
9
- const MAX_QUEUE_LENGTH = 10 ;
10
-
11
7
export class DuplicateCheckerPlugin implements IEventPlugin {
12
8
public priority : number = 40 ;
13
9
public name : string = 'DuplicateCheckerPlugin' ;
14
10
15
- private recentlyProcessedErrors : TimestampedHash [ ] = [ ] ;
16
-
17
- public run ( context : EventPluginContext , next ?: ( ) => void ) : void {
18
- if ( context . event . type === 'error' ) {
19
- let error = context . event . data [ ERROR_KEY ] ;
20
- let isDuplicate = this . checkDuplicate ( error , context . log ) ;
21
- if ( isDuplicate ) {
22
- context . cancelled = true ;
23
- return ;
24
- }
25
- }
11
+ private _processedHashcodes : TimestampedHash [ ] = [ ] ;
12
+ private _getCurrentTime : ( ) => number ;
26
13
27
- next && next ( ) ;
14
+ constructor ( getCurrentTime :( ) => number = ( ) => Date . now ( ) ) {
15
+ this . _getCurrentTime = getCurrentTime ;
28
16
}
29
17
30
- private getNow ( ) {
31
- return Date . now ( ) ;
32
- }
18
+ public run ( context : EventPluginContext , next ?: ( ) => void ) : void {
19
+ function isDuplicate ( error : IInnerError , processedHashcodes , now , log : ILog ) : boolean {
20
+ while ( error ) {
21
+ let hashCode = Utils . getHashCode ( error . stack_trace && JSON . stringify ( error . stack_trace ) ) ;
33
22
34
- private checkDuplicate ( error : IInnerError , log : ILog ) : boolean {
35
- function getHashCodeForError ( err : IInnerError ) : number {
36
- if ( ! err . stack_trace ) {
37
- return null ;
38
- }
23
+ // Only process the unique errors times within a 2 second window.
24
+ if ( hashCode && processedHashcodes . some ( h => h . hash === hashCode && h . timestamp >= ( now - 2000 ) ) ) {
25
+ log . info ( `Ignoring duplicate error event hash: ${ hashCode } ` ) ;
26
+ return true ;
27
+ }
39
28
40
- return Utils . getHashCode ( JSON . stringify ( err . stack_trace ) ) ;
41
- }
29
+ // Add this exception to our list of recent processed errors.
30
+ processedHashcodes . push ( { hash : hashCode , timestamp : now } ) ;
42
31
43
- let now = this . getNow ( ) ;
44
- let repeatWindow = now - WINDOW_MILLISECONDS ;
45
- let hashCode : number ;
46
- while ( error ) {
47
- hashCode = getHashCodeForError ( error ) ;
32
+ // Only keep the last 20 recent errors.
33
+ while ( processedHashcodes . length > 20 ) {
34
+ processedHashcodes . shift ( ) ;
35
+ }
48
36
49
- // make sure that we don't process the same error multiple times within the repeat window
50
- if ( hashCode && this . recentlyProcessedErrors . some ( h =>
51
- h . hash === hashCode && h . timestamp >= repeatWindow ) ) {
52
- log . info ( `Ignoring duplicate error event: hash=${ hashCode } ` ) ;
53
- return true ;
37
+ error = error . inner ;
54
38
}
55
39
56
- // add this exception to our list of recent errors that we have processed
57
- this . recentlyProcessedErrors . push ( { hash : hashCode , timestamp : now } ) ;
40
+ return false ;
41
+ }
58
42
59
- // only keep the last 10 recent errors
60
- while ( this . recentlyProcessedErrors . length > MAX_QUEUE_LENGTH ) {
61
- this . recentlyProcessedErrors . shift ( ) ;
43
+ if ( context . event . type === 'error' ) {
44
+ if ( isDuplicate ( context . event . data [ '@error' ] , this . _processedHashcodes , this . _getCurrentTime ( ) , context . log ) ) {
45
+ context . cancelled = true ;
46
+ return ;
62
47
}
63
-
64
- error = error . inner ;
65
48
}
66
49
67
- return false ;
50
+ next && next ( ) ;
68
51
}
69
52
}
70
53
0 commit comments