Skip to content

Commit bc802ed

Browse files
committed
Merge pull request #35 from exceptionless/feature/deduplication
Implemented DuplicateChecker
2 parents 556848f + 5806f96 commit bc802ed

15 files changed

+397
-61
lines changed

dist/exceptionless.d.ts

+38-30
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,37 @@ export interface IEnvironmentInfo {
326326
runtime_version?: string;
327327
data?: any;
328328
}
329+
export interface IParameter {
330+
data?: any;
331+
generic_arguments?: string[];
332+
name?: string;
333+
type?: string;
334+
type_namespace?: string;
335+
}
336+
export interface IMethod {
337+
data?: any;
338+
generic_arguments?: string[];
339+
parameters?: IParameter[];
340+
is_signature_target?: boolean;
341+
declaring_namespace?: string;
342+
declaring_type?: string;
343+
name?: string;
344+
module_id?: number;
345+
}
346+
export interface IStackFrame extends IMethod {
347+
file_name?: string;
348+
line_number?: number;
349+
column?: number;
350+
}
351+
export interface IInnerError {
352+
message?: string;
353+
type?: string;
354+
code?: string;
355+
data?: any;
356+
inner?: IInnerError;
357+
stack_trace?: IStackFrame[];
358+
target_method?: IMethod;
359+
}
329360
export declare class ConfigurationDefaultsPlugin implements IEventPlugin {
330361
priority: number;
331362
name: string;
@@ -358,36 +389,13 @@ export declare class SubmissionMethodPlugin implements IEventPlugin {
358389
name: string;
359390
run(context: EventPluginContext, next?: () => void): void;
360391
}
361-
export interface IParameter {
362-
data?: any;
363-
generic_arguments?: string[];
364-
name?: string;
365-
type?: string;
366-
type_namespace?: string;
367-
}
368-
export interface IMethod {
369-
data?: any;
370-
generic_arguments?: string[];
371-
parameters?: IParameter[];
372-
is_signature_target?: boolean;
373-
declaring_namespace?: string;
374-
declaring_type?: string;
375-
name?: string;
376-
module_id?: number;
377-
}
378-
export interface IStackFrame extends IMethod {
379-
file_name?: string;
380-
line_number?: number;
381-
column?: number;
382-
}
383-
export interface IInnerError {
384-
message?: string;
385-
type?: string;
386-
code?: string;
387-
data?: any;
388-
inner?: IInnerError;
389-
stack_trace?: IStackFrame[];
390-
target_method?: IMethod;
392+
export declare class DuplicateCheckerPlugin implements IEventPlugin {
393+
priority: number;
394+
name: string;
395+
private recentlyProcessedErrors;
396+
run(context: EventPluginContext, next?: () => void): void;
397+
private getNow();
398+
private checkDuplicate(error, log);
391399
}
392400
export interface IError extends IInnerError {
393401
modules?: IModule[];

dist/exceptionless.js

+66-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/exceptionless.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/exceptionless.min.js

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/exceptionless.min.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/exceptionless.node.js

+66-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/exceptionless.node.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/plugins/EventPluginManager.ts

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { ModuleInfoPlugin } from './default/ModuleInfoPlugin';
77
import { RequestInfoPlugin } from './default/RequestInfoPlugin';
88
import { EnvironmentInfoPlugin } from './default/EnvironmentInfoPlugin';
99
import { SubmissionMethodPlugin } from './default/SubmissionMethodPlugin';
10+
import { DuplicateCheckerPlugin } from './default/DuplicateCheckerPlugin';
1011

1112
export class EventPluginManager {
1213
public static run(context:EventPluginContext, callback:(context?:EventPluginContext) => void): void {
@@ -43,6 +44,7 @@ export class EventPluginManager {
4344
public static addDefaultPlugins(config:Configuration): void {
4445
config.addPlugin(new ConfigurationDefaultsPlugin());
4546
config.addPlugin(new ErrorPlugin());
47+
config.addPlugin(new DuplicateCheckerPlugin());
4648
config.addPlugin(new ModuleInfoPlugin());
4749
config.addPlugin(new RequestInfoPlugin());
4850
config.addPlugin(new EnvironmentInfoPlugin());
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import { ContextData } from '../ContextData';
2+
import { EventPluginContext } from '../EventPluginContext';
3+
import { DuplicateCheckerPlugin } from './DuplicateCheckerPlugin';
4+
import { ErrorPlugin } from './ErrorPlugin';
5+
import { createFixture } from './EventPluginTestFixture';
6+
7+
describe('DuplicateCheckerPlugin', () => {
8+
9+
let target: DuplicateCheckerPlugin;
10+
let now: number;
11+
12+
beforeEach(() => {
13+
target = new DuplicateCheckerPlugin();
14+
(<any>target).getNow = () => now;
15+
now = 0;
16+
});
17+
18+
function run(exception: Error) {
19+
let context: EventPluginContext;
20+
let contextData: ContextData;
21+
({
22+
context,
23+
contextData
24+
} = createFixture());
25+
26+
contextData.setException(exception);
27+
28+
let errorPlugin = new ErrorPlugin();
29+
errorPlugin.run(context);
30+
target.run(context);
31+
32+
return context;
33+
}
34+
35+
it('should ignore duplicate within window', () => {
36+
let exception = createException([{
37+
name: 'methodA'
38+
}]);
39+
run(exception);
40+
let contextOfSecondRun = run(exception);
41+
expect(contextOfSecondRun.cancelled).toBeTruthy();
42+
});
43+
44+
it('shouldn\'t ignore error without stack', () => {
45+
let exception = createException();
46+
run(exception);
47+
let contextOfSecondRun = run(exception);
48+
expect(contextOfSecondRun.cancelled).toBeFalsy();
49+
});
50+
51+
it('shouldn\'t ignore different stack within window', () => {
52+
let exception1 = createException([{
53+
name: 'methodA'
54+
}]);
55+
run(exception1);
56+
let exception2 = createException([{
57+
name: 'methodB'
58+
}]);
59+
let contextOfSecondRun = run(exception2);
60+
expect(contextOfSecondRun.cancelled).toBeFalsy();
61+
});
62+
63+
it('shouldn\'t ignore duplicate after window', () => {
64+
let exception = createException([{
65+
name: 'methodA'
66+
}]);
67+
run(exception);
68+
69+
now = 3000;
70+
let contextOfSecondRun = run(exception);
71+
expect(contextOfSecondRun.cancelled).toBeFalsy();
72+
});
73+
});
74+
75+
function createException(stack?) {
76+
try {
77+
throw new Error();
78+
} catch (e) {
79+
e.testStack = stack;
80+
return e;
81+
}
82+
}

0 commit comments

Comments
 (0)