1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
import { Severity } from '@sentry/types';
import type { Logger, LoggerFactory } from '../types';
import type {
captureException,
captureMessage,
addBreadcrumb,
ErrorHub,
ErrorKitConfig,
} from './types';
type PartialSentryModule = {
captureException: typeof captureException;
captureMessage: typeof captureMessage;
addBreadcrumb: typeof addBreadcrumb;
};
export type ErrorKitInstance = InstanceType<typeof ErrorKit>;
export const setupErrorKit = (
config: ErrorKitConfig,
loggerFactory: LoggerFactory,
): ErrorKitInstance | undefined => {
if (typeof window === 'undefined') return;
const log = loggerFactory.loggerFor('errorkit');
const isMultiDev = window.location.href.includes('multidev');
const BUILD_ENV = process.env.NODE_ENV;
const isErrorKitEnabled = BUILD_ENV === 'production' && !isMultiDev;
const initializeErrorKit =
async (): Promise<PartialSentryModule | null> => {
let sentry: PartialSentryModule | null = null;
if (isErrorKitEnabled) {
try {
const { createSentryConfig } = await import(
'@amp-metrics/sentrykit'
);
const Sentry = await import('@sentry/browser');
Sentry.init(createSentryConfig(config));
sentry = {
addBreadcrumb: Sentry.addBreadcrumb,
captureException: Sentry.captureException,
captureMessage: Sentry.captureMessage,
};
} catch (e) {
log.error('something went wrong setting up errorKit', e);
}
}
return sentry;
};
return new ErrorKit(initializeErrorKit(), log, isErrorKitEnabled);
};
class ErrorKit implements ErrorHub {
private readonly sentry: Promise<PartialSentryModule | null>;
private readonly logger: Logger;
private readonly isErrorKitEnabled: boolean;
constructor(
sentry: Promise<PartialSentryModule | null>,
log: Logger,
isErrorKitEnabled: boolean,
) {
this.sentry = sentry;
this.logger = log;
this.isErrorKitEnabled = isErrorKitEnabled;
if (!isErrorKitEnabled) {
log.debug('errorkit is disabled');
}
}
async captureMessage(message: string) {
if (!this.isErrorKitEnabled) return;
const sentry = await this.sentry;
if (sentry) {
sentry.addBreadcrumb({
category: 'log.warn',
level: Severity.Warning,
});
sentry.captureMessage(message, Severity.Warning);
} else {
this.logger.warn(`${message} was not sent to errorKit`);
}
}
async captureException(exception: Error) {
if (!this.isErrorKitEnabled) return;
const sentry = await this.sentry;
if (sentry) {
sentry.addBreadcrumb({
type: 'error',
category: 'error',
level: Severity.Error,
});
sentry.captureException(exception);
} else {
this.logger.warn(
`The following exception was not sent to errorKit:`,
exception,
);
}
}
}
|