-
-
Notifications
You must be signed in to change notification settings - Fork 9.4k
/
Copy pathwithTelemetry.ts
92 lines (75 loc) · 2.81 KB
/
withTelemetry.ts
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
import prompts from 'prompts';
import type { CLIOptions, CoreConfig } from '@storybook/types';
import { loadAllPresets, cache } from '@storybook/core-common';
import { telemetry, getPrecedingUpgrade } from '@storybook/telemetry';
import type { EventType } from '@storybook/telemetry';
type TelemetryOptions = {
cliOptions?: CLIOptions;
presetOptions?: Parameters<typeof loadAllPresets>[0];
};
const promptCrashReports = async () => {
if (process.env.CI && process.env.NODE_ENV !== 'test') {
return undefined;
}
const { enableCrashReports } = await prompts({
type: 'confirm',
name: 'enableCrashReports',
message: `Would you like to send crash reports to Storybook?`,
initial: true,
});
await cache.set('enableCrashReports', enableCrashReports);
return enableCrashReports;
};
type ErrorLevel = 'none' | 'error' | 'full';
async function getErrorLevel({ cliOptions, presetOptions }: TelemetryOptions): Promise<ErrorLevel> {
if (cliOptions?.disableTelemetry) return 'none';
// If we are running init or similar, we just have to go with true here
if (!presetOptions) return 'full';
// should we load the preset?
const presets = await loadAllPresets({
corePresets: [require.resolve('./presets/common-preset')],
overridePresets: [],
...presetOptions,
});
// If the user has chosen to enable/disable crash reports in main.js
// or disabled telemetry, we can return that
const core = await presets.apply<CoreConfig>('core');
if (core?.enableCrashReports !== undefined) return core.enableCrashReports ? 'full' : 'error';
if (core?.disableTelemetry) return 'none';
// Deal with typo, remove in future version (7.1?)
const valueFromCache =
(await cache.get('enableCrashReports')) ?? (await cache.get('enableCrashreports'));
if (valueFromCache !== undefined) return valueFromCache ? 'full' : 'error';
const valueFromPrompt = await promptCrashReports();
if (valueFromPrompt !== undefined) return valueFromPrompt ? 'full' : 'error';
return 'full';
}
export async function withTelemetry(
eventType: EventType,
options: TelemetryOptions,
run: () => Promise<void>
) {
telemetry('boot', { eventType }, { stripMetadata: true });
try {
await run();
} catch (error) {
try {
const errorLevel = await getErrorLevel(options);
if (errorLevel !== 'none') {
const precedingUpgrade = await getPrecedingUpgrade();
await telemetry(
'error',
{ eventType, precedingUpgrade, error: errorLevel === 'full' ? error : undefined },
{
immediate: true,
configDir: options.cliOptions?.configDir || options.presetOptions?.configDir,
enableCrashReports: errorLevel === 'full',
}
);
}
} catch (err) {
// if this throws an error, we just move on
}
throw error;
}
}