sentry-vir 4.0.3 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE-MIT +1 -1
- package/dist/event-context/event-context.d.ts +6 -3
- package/dist/event-context/extra-context.error.d.ts +3 -1
- package/dist/event-context/extra-context.error.js +8 -1
- package/dist/event-context/extra-event-context.d.ts +22 -1
- package/dist/event-context/extra-event-context.js +39 -0
- package/dist/logging/handle-error.js +14 -1
- package/dist/logging/send-log.js +18 -6
- package/dist/logging/sentry-client-for-logging.d.ts +1 -1
- package/dist/processing/throttling.d.ts +16 -13
- package/dist/processing/throttling.js +41 -33
- package/package.json +26 -25
package/LICENSE-MIT
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type JsonCompatibleObject, type PartialWithUndefined } from '@augment-vir/common';
|
|
2
|
-
import { type ScopeContext, type setTags } from '@sentry/core';
|
|
2
|
+
import { type Attachment, type ScopeContext, type setTags } from '@sentry/core';
|
|
3
3
|
import { type EventSeverityEnum } from './event-severity.js';
|
|
4
|
+
export type { Attachment } from '@sentry/core';
|
|
4
5
|
/**
|
|
5
6
|
* Used for all extra context types. While keys must be strings, values can be whatever but must be
|
|
6
7
|
* JSON compatible.
|
|
@@ -9,12 +10,13 @@ export type EventExtraContext = JsonCompatibleObject;
|
|
|
9
10
|
/** Allowed tag value types for Sentry event tags. */
|
|
10
11
|
export type EventTags = Parameters<typeof setTags>[0];
|
|
11
12
|
/**
|
|
12
|
-
* Combined context and
|
|
13
|
-
* optional.
|
|
13
|
+
* Combined context, tags, and attachments parameter used for event logging functions. All
|
|
14
|
+
* properties are optional.
|
|
14
15
|
*/
|
|
15
16
|
export type EventContextAndTags = PartialWithUndefined<{
|
|
16
17
|
context: EventExtraContext;
|
|
17
18
|
tags: EventTags;
|
|
19
|
+
attachments: ReadonlyArray<Attachment>;
|
|
18
20
|
}>;
|
|
19
21
|
/** Function that generates extra event context. */
|
|
20
22
|
export type EventExtraContextCreator = () => EventExtraContext;
|
|
@@ -22,6 +24,7 @@ export type EventExtraContextCreator = () => EventExtraContext;
|
|
|
22
24
|
export type EventDetails = {
|
|
23
25
|
extraContext?: EventExtraContext | undefined;
|
|
24
26
|
tags?: EventTags | undefined;
|
|
27
|
+
attachments?: ReadonlyArray<Attachment> | undefined;
|
|
25
28
|
severity: EventSeverityEnum;
|
|
26
29
|
};
|
|
27
30
|
/** Options for creating contexts. Used internally. */
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { type Attachment } from '@sentry/core';
|
|
1
2
|
import { type EventContextAndTags, type EventExtraContext, type EventTags } from './event-context.js';
|
|
2
|
-
import { extraEventContextSymbol, extraEventTagsSymbol } from './extra-event-context.js';
|
|
3
|
+
import { extraEventAttachmentsSymbol, extraEventContextSymbol, extraEventTagsSymbol } from './extra-event-context.js';
|
|
3
4
|
/**
|
|
4
5
|
* Constructs an error with extra event context attached to it in the same way that
|
|
5
6
|
* throwWithExtraContext attaches data.
|
|
@@ -14,6 +15,7 @@ import { extraEventContextSymbol, extraEventTagsSymbol } from './extra-event-con
|
|
|
14
15
|
export declare class ExtraContextError extends Error {
|
|
15
16
|
readonly [extraEventContextSymbol]: EventExtraContext | undefined;
|
|
16
17
|
readonly [extraEventTagsSymbol]: EventTags | undefined;
|
|
18
|
+
readonly [extraEventAttachmentsSymbol]: ReadonlyArray<Attachment> | undefined;
|
|
17
19
|
constructor(message: string, extraData: EventContextAndTags);
|
|
18
20
|
}
|
|
19
21
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ensureError } from '@augment-vir/common';
|
|
2
|
-
import { extraEventContextSymbol, extraEventTagsSymbol, } from './extra-event-context.js';
|
|
2
|
+
import { extraEventAttachmentsSymbol, extraEventContextSymbol, extraEventTagsSymbol, } from './extra-event-context.js';
|
|
3
3
|
/**
|
|
4
4
|
* Constructs an error with extra event context attached to it in the same way that
|
|
5
5
|
* throwWithExtraContext attaches data.
|
|
@@ -14,6 +14,7 @@ import { extraEventContextSymbol, extraEventTagsSymbol, } from './extra-event-co
|
|
|
14
14
|
export class ExtraContextError extends Error {
|
|
15
15
|
[extraEventContextSymbol];
|
|
16
16
|
[extraEventTagsSymbol];
|
|
17
|
+
[extraEventAttachmentsSymbol];
|
|
17
18
|
constructor(message, extraData) {
|
|
18
19
|
super(message);
|
|
19
20
|
if (extraData.context) {
|
|
@@ -22,6 +23,9 @@ export class ExtraContextError extends Error {
|
|
|
22
23
|
if (extraData.tags) {
|
|
23
24
|
this[extraEventTagsSymbol] = extraData.tags;
|
|
24
25
|
}
|
|
26
|
+
if (extraData.attachments) {
|
|
27
|
+
this[extraEventAttachmentsSymbol] = extraData.attachments;
|
|
28
|
+
}
|
|
25
29
|
}
|
|
26
30
|
}
|
|
27
31
|
/**
|
|
@@ -36,5 +40,8 @@ export function throwWithExtraContext(originalError, extraData) {
|
|
|
36
40
|
if (extraData.tags) {
|
|
37
41
|
error[extraEventTagsSymbol] = extraData.tags;
|
|
38
42
|
}
|
|
43
|
+
if (extraData.attachments) {
|
|
44
|
+
error[extraEventAttachmentsSymbol] = extraData.attachments;
|
|
45
|
+
}
|
|
39
46
|
throw error;
|
|
40
47
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Event, type EventHint } from '@sentry/core';
|
|
1
|
+
import { type Attachment, type Event, type EventHint } from '@sentry/core';
|
|
2
2
|
import { type EventExtraContext, type EventTags } from './event-context.js';
|
|
3
3
|
/**
|
|
4
4
|
* Symbol used to attach extra event context to events. This is particularly useful for errors so
|
|
@@ -10,6 +10,11 @@ export declare const extraEventContextSymbol: unique symbol;
|
|
|
10
10
|
* attaching tag data to thrown errors.
|
|
11
11
|
*/
|
|
12
12
|
export declare const extraEventTagsSymbol: unique symbol;
|
|
13
|
+
/**
|
|
14
|
+
* Symbol used to attach extra event attachments to events. Used alongside extraEventContextSymbol
|
|
15
|
+
* for attaching file data to thrown errors.
|
|
16
|
+
*/
|
|
17
|
+
export declare const extraEventAttachmentsSymbol: unique symbol;
|
|
13
18
|
/** Simply describes an object that has extra event context. */
|
|
14
19
|
export type HasExtraContext = {
|
|
15
20
|
[extraEventContextSymbol]: EventExtraContext;
|
|
@@ -18,10 +23,16 @@ export type HasExtraContext = {
|
|
|
18
23
|
export type HasExtraTags = {
|
|
19
24
|
[extraEventTagsSymbol]: EventTags;
|
|
20
25
|
};
|
|
26
|
+
/** Simply describes an object that has extra event attachments. */
|
|
27
|
+
export type HasExtraAttachments = {
|
|
28
|
+
[extraEventAttachmentsSymbol]: ReadonlyArray<Attachment>;
|
|
29
|
+
};
|
|
21
30
|
/** Type guard for whether any given input has extra event context. */
|
|
22
31
|
export declare function hasExtraEventContext(input: unknown): input is HasExtraContext;
|
|
23
32
|
/** Type guard for whether any given input has extra event tags. */
|
|
24
33
|
export declare function hasExtraEventTags(input: unknown): input is HasExtraTags;
|
|
34
|
+
/** Type guard for whether any given input has extra event attachments. */
|
|
35
|
+
export declare function hasExtraEventAttachments(input: unknown): input is HasExtraAttachments;
|
|
25
36
|
/**
|
|
26
37
|
* Checks if extra event context has been injected into the input via extraEventContextSymbol and,
|
|
27
38
|
* if so, extracts it.
|
|
@@ -32,6 +43,11 @@ export declare function extractExtraContentFromSymbol(input: unknown): EventExtr
|
|
|
32
43
|
* extracts them.
|
|
33
44
|
*/
|
|
34
45
|
export declare function extractExtraTagsFromSymbol(input: unknown): EventTags | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* Checks if extra event attachments have been injected into the input via
|
|
48
|
+
* extraEventAttachmentsSymbol and, if so, extracts them.
|
|
49
|
+
*/
|
|
50
|
+
export declare function extractExtraAttachmentsFromSymbol(input: unknown): ReadonlyArray<Attachment> | undefined;
|
|
35
51
|
/**
|
|
36
52
|
* Tries to extract extra event context via extraEventContextSymbol. Returns undefined if there is
|
|
37
53
|
* no extra event context.
|
|
@@ -42,3 +58,8 @@ export declare function extractExtraEventContext(event: EventHint | Event): Even
|
|
|
42
58
|
* extra event tags.
|
|
43
59
|
*/
|
|
44
60
|
export declare function extractExtraEventTags(event: EventHint | Event): EventTags | undefined;
|
|
61
|
+
/**
|
|
62
|
+
* Tries to extract extra event attachments via extraEventAttachmentsSymbol. Returns undefined if
|
|
63
|
+
* there are no extra event attachments.
|
|
64
|
+
*/
|
|
65
|
+
export declare function extractExtraEventAttachments(event: EventHint | Event): ReadonlyArray<Attachment> | undefined;
|
|
@@ -9,6 +9,11 @@ export const extraEventContextSymbol = Symbol('extra-event-context');
|
|
|
9
9
|
* attaching tag data to thrown errors.
|
|
10
10
|
*/
|
|
11
11
|
export const extraEventTagsSymbol = Symbol('extra-event-tags');
|
|
12
|
+
/**
|
|
13
|
+
* Symbol used to attach extra event attachments to events. Used alongside extraEventContextSymbol
|
|
14
|
+
* for attaching file data to thrown errors.
|
|
15
|
+
*/
|
|
16
|
+
export const extraEventAttachmentsSymbol = Symbol('extra-event-attachments');
|
|
12
17
|
/** Type guard for whether any given input has extra event context. */
|
|
13
18
|
export function hasExtraEventContext(input) {
|
|
14
19
|
return check.hasKey(input, extraEventContextSymbol) && !!input[extraEventContextSymbol];
|
|
@@ -17,6 +22,10 @@ export function hasExtraEventContext(input) {
|
|
|
17
22
|
export function hasExtraEventTags(input) {
|
|
18
23
|
return check.hasKey(input, extraEventTagsSymbol) && !!input[extraEventTagsSymbol];
|
|
19
24
|
}
|
|
25
|
+
/** Type guard for whether any given input has extra event attachments. */
|
|
26
|
+
export function hasExtraEventAttachments(input) {
|
|
27
|
+
return check.hasKey(input, extraEventAttachmentsSymbol) && !!input[extraEventAttachmentsSymbol];
|
|
28
|
+
}
|
|
20
29
|
/**
|
|
21
30
|
* Checks if extra event context has been injected into the input via extraEventContextSymbol and,
|
|
22
31
|
* if so, extracts it.
|
|
@@ -39,6 +48,16 @@ export function extractExtraTagsFromSymbol(input) {
|
|
|
39
48
|
}
|
|
40
49
|
return undefined;
|
|
41
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Checks if extra event attachments have been injected into the input via
|
|
53
|
+
* extraEventAttachmentsSymbol and, if so, extracts them.
|
|
54
|
+
*/
|
|
55
|
+
export function extractExtraAttachmentsFromSymbol(input) {
|
|
56
|
+
if (hasExtraEventAttachments(input)) {
|
|
57
|
+
return input[extraEventAttachmentsSymbol];
|
|
58
|
+
}
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
42
61
|
/**
|
|
43
62
|
* Tries to extract extra event context via extraEventContextSymbol. Returns undefined if there is
|
|
44
63
|
* no extra event context.
|
|
@@ -83,3 +102,23 @@ export function extractExtraEventTags(event) {
|
|
|
83
102
|
return undefined;
|
|
84
103
|
}
|
|
85
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Tries to extract extra event attachments via extraEventAttachmentsSymbol. Returns undefined if
|
|
107
|
+
* there are no extra event attachments.
|
|
108
|
+
*/
|
|
109
|
+
export function extractExtraEventAttachments(event) {
|
|
110
|
+
const fromRootSymbol = extractExtraAttachmentsFromSymbol(event);
|
|
111
|
+
const fromSubSymbol = 'originalException' in event
|
|
112
|
+
? extractExtraAttachmentsFromSymbol(event.originalException)
|
|
113
|
+
: undefined;
|
|
114
|
+
const combined = [
|
|
115
|
+
...(fromRootSymbol || []),
|
|
116
|
+
...(fromSubSymbol || []),
|
|
117
|
+
];
|
|
118
|
+
if (combined.length) {
|
|
119
|
+
return combined;
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { extractErrorMessage } from '@augment-vir/common';
|
|
2
2
|
import { convertEventDetailsToSentryContext, } from '../event-context/event-context.js';
|
|
3
3
|
import { EventSeverityEnum } from '../event-context/event-severity.js';
|
|
4
|
+
import { extractExtraAttachmentsFromSymbol } from '../event-context/extra-event-context.js';
|
|
4
5
|
import { LoggingState, logToConsoleWithoutSentry } from '../processing/log-to-console.js';
|
|
5
6
|
import { addPrematureEvent } from './premature-events.js';
|
|
6
7
|
import { sentryClientForLogging } from './sentry-client-for-logging.js';
|
|
@@ -34,7 +35,19 @@ function internalHandleError(error, eventOptions, options) {
|
|
|
34
35
|
tags: eventOptions?.tags,
|
|
35
36
|
severity: EventSeverityEnum.Error,
|
|
36
37
|
}, options);
|
|
37
|
-
const
|
|
38
|
+
const client = sentryClientForLogging;
|
|
39
|
+
const allAttachments = [
|
|
40
|
+
...(eventOptions?.attachments || []),
|
|
41
|
+
...(extractExtraAttachmentsFromSymbol(error) || []),
|
|
42
|
+
];
|
|
43
|
+
const eventId = allAttachments.length
|
|
44
|
+
? client.withScope((scope) => {
|
|
45
|
+
allAttachments.forEach((attachment) => {
|
|
46
|
+
scope.addAttachment(attachment);
|
|
47
|
+
});
|
|
48
|
+
return client.captureException(error, scopeContext);
|
|
49
|
+
})
|
|
50
|
+
: client.captureException(error, scopeContext);
|
|
38
51
|
return eventId;
|
|
39
52
|
}
|
|
40
53
|
catch (caught) {
|
package/dist/logging/send-log.js
CHANGED
|
@@ -20,6 +20,7 @@ function wrapLogWithSeverity(severity) {
|
|
|
20
20
|
return sendLogToSentry(info, {
|
|
21
21
|
extraContext: eventOptions?.context,
|
|
22
22
|
tags: eventOptions?.tags,
|
|
23
|
+
attachments: eventOptions?.attachments,
|
|
23
24
|
severity,
|
|
24
25
|
}, {
|
|
25
26
|
wasSentPrematurely: false,
|
|
@@ -54,12 +55,23 @@ function sendLogToSentry(logInfo, eventDetails, options) {
|
|
|
54
55
|
return undefined;
|
|
55
56
|
}
|
|
56
57
|
const scopeContext = convertEventDetailsToSentryContext(eventDetails, options);
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
58
|
+
const client = sentryClientForLogging;
|
|
59
|
+
function captureWithClient() {
|
|
60
|
+
return check.isString(resolvedLogInfo)
|
|
61
|
+
? client.captureMessage(resolvedLogInfo, scopeContext)
|
|
62
|
+
: client.captureEvent({
|
|
63
|
+
...resolvedLogInfo,
|
|
64
|
+
...scopeContext,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
const eventId = eventDetails.attachments?.length
|
|
68
|
+
? client.withScope((scope) => {
|
|
69
|
+
eventDetails.attachments?.forEach((attachment) => {
|
|
70
|
+
scope.addAttachment(attachment);
|
|
71
|
+
});
|
|
72
|
+
return captureWithClient();
|
|
73
|
+
})
|
|
74
|
+
: captureWithClient();
|
|
63
75
|
return eventId;
|
|
64
76
|
}
|
|
65
77
|
catch (caught) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type MaybePromise } from '@augment-vir/common';
|
|
2
2
|
import { type SentryDep } from '../env/execution-env.js';
|
|
3
3
|
/** The bare minimum Sentry client needed for logging events. */
|
|
4
|
-
export type SentryClientForLogging = Pick<SentryDep, 'captureMessage' | 'captureException' | 'captureEvent' | 'setTags'>;
|
|
4
|
+
export type SentryClientForLogging = Pick<SentryDep, 'captureMessage' | 'captureException' | 'captureEvent' | 'setTags' | 'withScope'>;
|
|
5
5
|
/** Internal sentry client used for logging. */
|
|
6
6
|
export declare let sentryClientForLogging: SentryClientForLogging | undefined;
|
|
7
7
|
/**
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type PartialWithUndefined } from '@augment-vir/common';
|
|
2
2
|
import { type ErrorEvent, type EventHint, type TransactionEvent } from '@sentry/core';
|
|
3
3
|
import { type AnyDuration, type FullDate, type UtcTimezone } from 'date-vir';
|
|
4
|
+
import { FuzzyIndex, type FuzzyIndexKey } from 'fuzzy-vir';
|
|
4
5
|
/**
|
|
5
6
|
* Type for entries in {@link throttleCache}.
|
|
6
7
|
*
|
|
@@ -9,14 +10,21 @@ import { type AnyDuration, type FullDate, type UtcTimezone } from 'date-vir';
|
|
|
9
10
|
export type ThrottleCacheEntry = {
|
|
10
11
|
intervalCount: number;
|
|
11
12
|
intervalStartAt: FullDate<UtcTimezone>;
|
|
12
|
-
throttleStartedAt: FullDate<UtcTimezone> | undefined;
|
|
13
13
|
};
|
|
14
14
|
/**
|
|
15
|
-
* The current throttle cache
|
|
15
|
+
* The current throttle cache, keyed by a fuzzy cluster key so near-duplicate error messages share a
|
|
16
|
+
* throttle bucket.
|
|
16
17
|
*
|
|
17
18
|
* @category Internal
|
|
18
19
|
*/
|
|
19
|
-
export declare const throttleCache: Map<
|
|
20
|
+
export declare const throttleCache: Map<FuzzyIndexKey, ThrottleCacheEntry>;
|
|
21
|
+
/**
|
|
22
|
+
* Fuzzy index used to group near-duplicate error messages together so they share a single throttle
|
|
23
|
+
* bucket. The `onEvict` hook keeps {@link throttleCache} in sync when a cluster is dropped.
|
|
24
|
+
*
|
|
25
|
+
* @category Internal
|
|
26
|
+
*/
|
|
27
|
+
export declare const fuzzyErrorIndex: FuzzyIndex;
|
|
20
28
|
/**
|
|
21
29
|
* Throttling options.
|
|
22
30
|
*
|
|
@@ -24,19 +32,14 @@ export declare const throttleCache: Map<string, ThrottleCacheEntry>;
|
|
|
24
32
|
*/
|
|
25
33
|
export type ThrottleOptions = {
|
|
26
34
|
disableThrottling: boolean;
|
|
27
|
-
/**
|
|
28
|
-
* When throttling begins, this determines how much time must pass before the error will be
|
|
29
|
-
* logged again.
|
|
30
|
-
*/
|
|
35
|
+
/** Duration over which up to `throttleThreshold` events of the same message are allowed. */
|
|
31
36
|
thresholdInterval: AnyDuration;
|
|
37
|
+
/** Disable the sentry log that fires the first time an error is throttled in an interval. */
|
|
38
|
+
disableThrottleLog: boolean;
|
|
32
39
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
40
|
+
* Within `thresholdInterval`, if an error message is logged more than this many times,
|
|
41
|
+
* additional events are dropped until the interval rolls over.
|
|
35
42
|
*/
|
|
36
|
-
throttleCooldown: AnyDuration;
|
|
37
|
-
/** Enable a sentry log that indicates that an error is being throttled. */
|
|
38
|
-
disableThrottleLog: boolean;
|
|
39
|
-
/** If an error is logged this many times within `logInterval`, it starts getting throttled. */
|
|
40
43
|
throttleThreshold: number;
|
|
41
44
|
};
|
|
42
45
|
/**
|
|
@@ -1,13 +1,26 @@
|
|
|
1
1
|
import { getOrSetFromMap, mergeDefinedProperties, } from '@augment-vir/common';
|
|
2
2
|
import { calculateRelativeDate, getNowInUtcTimezone, isDateAfter, } from 'date-vir';
|
|
3
|
+
import { FuzzyIndex } from 'fuzzy-vir';
|
|
3
4
|
import { sendLog } from '../logging/send-log.js';
|
|
4
5
|
import { extractOriginalMessage } from './event-processor.js';
|
|
5
6
|
/**
|
|
6
|
-
* The current throttle cache
|
|
7
|
+
* The current throttle cache, keyed by a fuzzy cluster key so near-duplicate error messages share a
|
|
8
|
+
* throttle bucket.
|
|
7
9
|
*
|
|
8
10
|
* @category Internal
|
|
9
11
|
*/
|
|
10
12
|
export const throttleCache = new Map();
|
|
13
|
+
/**
|
|
14
|
+
* Fuzzy index used to group near-duplicate error messages together so they share a single throttle
|
|
15
|
+
* bucket. The `onEvict` hook keeps {@link throttleCache} in sync when a cluster is dropped.
|
|
16
|
+
*
|
|
17
|
+
* @category Internal
|
|
18
|
+
*/
|
|
19
|
+
export const fuzzyErrorIndex = new FuzzyIndex({
|
|
20
|
+
onEvict(clusterKey) {
|
|
21
|
+
throttleCache.delete(clusterKey);
|
|
22
|
+
},
|
|
23
|
+
});
|
|
11
24
|
/**
|
|
12
25
|
* Default values for {@link ThrottleOptions}.
|
|
13
26
|
*
|
|
@@ -19,10 +32,7 @@ export const defaultThrottleOptions = {
|
|
|
19
32
|
hours: 1,
|
|
20
33
|
},
|
|
21
34
|
disableThrottleLog: false,
|
|
22
|
-
|
|
23
|
-
days: 1,
|
|
24
|
-
},
|
|
25
|
-
throttleThreshold: 50,
|
|
35
|
+
throttleThreshold: 500,
|
|
26
36
|
};
|
|
27
37
|
/**
|
|
28
38
|
* Determines if an event should be throttled based on previous event counts.
|
|
@@ -38,49 +48,47 @@ hint, userOptions = defaultThrottleOptions) {
|
|
|
38
48
|
if (options.disableThrottling) {
|
|
39
49
|
return false;
|
|
40
50
|
}
|
|
41
|
-
const errorKey = extractOriginalMessage(event, hint);
|
|
51
|
+
const errorKey = fuzzyErrorIndex.insert(extractOriginalMessage(event, hint));
|
|
42
52
|
const now = getNowInUtcTimezone();
|
|
43
53
|
const errorThrottleData = getOrSetFromMap(throttleCache, errorKey, () => {
|
|
44
54
|
return {
|
|
45
55
|
intervalCount: 0,
|
|
46
56
|
intervalStartAt: now,
|
|
47
|
-
throttleStartedAt: undefined,
|
|
48
57
|
};
|
|
49
58
|
});
|
|
50
|
-
errorThrottleData.intervalCount++;
|
|
51
|
-
const thresholdSurpassed = errorThrottleData.intervalCount > options.throttleThreshold;
|
|
52
|
-
if (thresholdSurpassed && !errorThrottleData.throttleStartedAt) {
|
|
53
|
-
errorThrottleData.throttleStartedAt = now;
|
|
54
|
-
if (options.disableThrottleLog) {
|
|
55
|
-
sendLog.warning(`Error throttled: ${errorKey}`);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
59
|
const intervalNeedsRestart = isDateAfter({
|
|
59
60
|
fullDate: now,
|
|
60
61
|
relativeTo: calculateRelativeDate(errorThrottleData.intervalStartAt, options.thresholdInterval),
|
|
61
62
|
});
|
|
62
63
|
if (intervalNeedsRestart) {
|
|
63
|
-
errorThrottleData.
|
|
64
|
-
if (
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
64
|
+
const suppressedCount = errorThrottleData.intervalCount - options.throttleThreshold;
|
|
65
|
+
if (suppressedCount > 0 && !options.disableThrottleLog) {
|
|
66
|
+
sendLog.warning(`Throttling ended after suppressing ${suppressedCount} events: ${errorKey}`, {
|
|
67
|
+
context: {
|
|
68
|
+
suppressedErrorKey: errorKey,
|
|
69
|
+
suppressedCount,
|
|
70
|
+
},
|
|
71
|
+
tags: {
|
|
72
|
+
suppressedErrorKey: errorKey,
|
|
73
|
+
},
|
|
74
|
+
});
|
|
73
75
|
}
|
|
76
|
+
errorThrottleData.intervalStartAt = now;
|
|
74
77
|
errorThrottleData.intervalCount = 0;
|
|
75
78
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
79
|
+
errorThrottleData.intervalCount++;
|
|
80
|
+
const shouldThrottle = errorThrottleData.intervalCount > options.throttleThreshold;
|
|
81
|
+
if (shouldThrottle &&
|
|
82
|
+
errorThrottleData.intervalCount === options.throttleThreshold + 1 &&
|
|
83
|
+
!options.disableThrottleLog) {
|
|
84
|
+
sendLog.warning(`Throttling started: ${errorKey}`, {
|
|
85
|
+
context: {
|
|
86
|
+
suppressedErrorKey: errorKey,
|
|
87
|
+
},
|
|
88
|
+
tags: {
|
|
89
|
+
suppressedErrorKey: errorKey,
|
|
90
|
+
},
|
|
80
91
|
});
|
|
81
|
-
if (shouldStopThrottle && !thresholdSurpassed) {
|
|
82
|
-
errorThrottleData.throttleStartedAt = undefined;
|
|
83
|
-
}
|
|
84
92
|
}
|
|
85
|
-
return
|
|
93
|
+
return shouldThrottle;
|
|
86
94
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sentry-vir",
|
|
3
|
-
"version": "4.0
|
|
3
|
+
"version": "4.2.0",
|
|
4
4
|
"description": "Easily use Sentry.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"config",
|
|
@@ -44,55 +44,56 @@
|
|
|
44
44
|
"test:update": "npm test update"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@augment-vir/assert": "^31.
|
|
48
|
-
"@augment-vir/common": "^31.
|
|
49
|
-
"@sentry/browser": "^10.
|
|
50
|
-
"@sentry/core": "^10.
|
|
51
|
-
"@sentry/node": "^10.
|
|
52
|
-
"date-vir": "^8.2
|
|
53
|
-
"
|
|
47
|
+
"@augment-vir/assert": "^31.70.0",
|
|
48
|
+
"@augment-vir/common": "^31.70.0",
|
|
49
|
+
"@sentry/browser": "^10.53.1",
|
|
50
|
+
"@sentry/core": "^10.53.1",
|
|
51
|
+
"@sentry/node": "^10.53.1",
|
|
52
|
+
"date-vir": "^8.3.2",
|
|
53
|
+
"fuzzy-vir": "^0.0.2",
|
|
54
|
+
"type-fest": "^5.6.0"
|
|
54
55
|
},
|
|
55
56
|
"devDependencies": {
|
|
56
|
-
"@augment-vir/test": "^31.
|
|
57
|
-
"@eslint/eslintrc": "^3.3.
|
|
57
|
+
"@augment-vir/test": "^31.70.0",
|
|
58
|
+
"@eslint/eslintrc": "^3.3.5",
|
|
58
59
|
"@eslint/js": "^9.39.2",
|
|
59
60
|
"@stylistic/eslint-plugin": "^5.10.0",
|
|
60
61
|
"@stylistic/eslint-plugin-ts": "^4.4.1",
|
|
61
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
62
|
+
"@typescript-eslint/eslint-plugin": "^8.59.4",
|
|
62
63
|
"@web/dev-server-esbuild": "^1.0.5",
|
|
63
64
|
"@web/test-runner": "^0.20.2",
|
|
64
65
|
"@web/test-runner-commands": "^0.9.0",
|
|
65
66
|
"@web/test-runner-playwright": "^0.11.1",
|
|
66
67
|
"@web/test-runner-visual-regression": "^0.10.0",
|
|
67
|
-
"cspell": "^
|
|
68
|
-
"dependency-cruiser": "^17.
|
|
69
|
-
"esbuild": "^0.
|
|
68
|
+
"cspell": "^10.0.0",
|
|
69
|
+
"dependency-cruiser": "^17.4.0",
|
|
70
|
+
"esbuild": "^0.28.0",
|
|
70
71
|
"eslint": "^9.39.2",
|
|
71
72
|
"eslint-config-prettier": "^10.1.8",
|
|
72
|
-
"eslint-plugin-jsdoc": "^
|
|
73
|
+
"eslint-plugin-jsdoc": "^63.0.0",
|
|
73
74
|
"eslint-plugin-monorepo-cop": "^1.0.2",
|
|
74
|
-
"eslint-plugin-playwright": "^2.
|
|
75
|
+
"eslint-plugin-playwright": "^2.10.4",
|
|
75
76
|
"eslint-plugin-prettier": "^5.5.5",
|
|
76
77
|
"eslint-plugin-require-extensions": "^0.1.3",
|
|
77
|
-
"eslint-plugin-sonarjs": "^4.0.
|
|
78
|
-
"eslint-plugin-unicorn": "^
|
|
78
|
+
"eslint-plugin-sonarjs": "^4.0.3",
|
|
79
|
+
"eslint-plugin-unicorn": "^64.0.0",
|
|
79
80
|
"istanbul-smart-text-reporter": "^1.1.5",
|
|
80
|
-
"markdown-code-example-inserter": "^3.0.
|
|
81
|
-
"npm-check-updates": "^
|
|
81
|
+
"markdown-code-example-inserter": "^3.0.5",
|
|
82
|
+
"npm-check-updates": "^22.2.0",
|
|
82
83
|
"prettier": "~3.3.3",
|
|
83
84
|
"prettier-plugin-interpolated-html-tags": "^2.0.1",
|
|
84
85
|
"prettier-plugin-jsdoc": "^1.8.0",
|
|
85
|
-
"prettier-plugin-multiline-arrays": "^4.1.
|
|
86
|
+
"prettier-plugin-multiline-arrays": "^4.1.8",
|
|
86
87
|
"prettier-plugin-organize-imports": "^4.3.0",
|
|
87
88
|
"prettier-plugin-packagejson": "^3.0.2",
|
|
88
89
|
"prettier-plugin-sort-json": "^4.2.0",
|
|
89
90
|
"prettier-plugin-toml": "^2.0.6",
|
|
90
91
|
"runstorm": "^1.0.0",
|
|
91
|
-
"typedoc": "^0.28.
|
|
92
|
+
"typedoc": "^0.28.19",
|
|
92
93
|
"typescript": "^5.9.3",
|
|
93
|
-
"typescript-eslint": "^8.
|
|
94
|
-
"virmator": "^14.
|
|
95
|
-
"vite": "^
|
|
94
|
+
"typescript-eslint": "^8.57.1",
|
|
95
|
+
"virmator": "^14.16.0",
|
|
96
|
+
"vite": "^8.0.13"
|
|
96
97
|
},
|
|
97
98
|
"engines": {
|
|
98
99
|
"node": ">=22"
|