1
1
/* eslint-disable no-console */
2
2
3
3
import { LogOptions } from '../core/logger/core.js' ;
4
-
5
- import { AstroTelemetry } from '@astrojs/telemetry' ;
6
4
import * as colors from 'kleur/colors' ;
7
5
import yargs from 'yargs-parser' ;
8
6
import { z } from 'zod' ;
7
+ import { telemetry } from '../events/index.js' ;
9
8
import * as event from '../events/index.js' ;
10
-
11
9
import add from '../core/add/index.js' ;
12
10
import build from '../core/build/index.js' ;
13
11
import { openConfig } from '../core/config.js' ;
14
12
import devServer from '../core/dev/index.js' ;
15
13
import { enableVerboseLogging , nodeLogDestination } from '../core/logger/node.js' ;
16
14
import { formatConfigErrorMessage , formatErrorMessage , printHelp } from '../core/messages.js' ;
17
15
import preview from '../core/preview/index.js' ;
18
- import { createSafeError } from '../core/util.js' ;
16
+ import { createSafeError , ASTRO_VERSION } from '../core/util.js' ;
19
17
import { check } from './check.js' ;
20
18
import { openInBrowser } from './open.js' ;
21
19
import * as telemetryHandler from './telemetry.js' ;
20
+ import { collectErrorMetadata } from '../core/errors.js' ;
21
+ import { eventError , eventConfigError } from '../events/index.js' ;
22
22
23
23
type Arguments = yargs . Arguments ;
24
24
type CLICommand =
@@ -61,9 +61,6 @@ function printAstroHelp() {
61
61
} ) ;
62
62
}
63
63
64
- // PACKAGE_VERSION is injected when we build and publish the astro package.
65
- const ASTRO_VERSION = process . env . PACKAGE_VERSION ?? 'development' ;
66
-
67
64
/** Display --version flag */
68
65
async function printVersion ( ) {
69
66
console . log ( ) ;
@@ -111,7 +108,6 @@ export async function cli(args: string[]) {
111
108
} else if ( flags . silent ) {
112
109
logging . level = 'silent' ;
113
110
}
114
- const telemetry = new AstroTelemetry ( { version : ASTRO_VERSION } ) ;
115
111
116
112
// Special CLI Commands: "add", "docs", "telemetry"
117
113
// These commands run before the user's config is parsed, and may have other special
@@ -120,19 +116,19 @@ export async function cli(args: string[]) {
120
116
switch ( cmd ) {
121
117
case 'add' : {
122
118
try {
123
- telemetry . record ( event . eventCliSession ( { cliCommand : cmd } ) ) ;
119
+ telemetry . record ( event . eventCliSession ( cmd ) ) ;
124
120
const packages = flags . _ . slice ( 3 ) as string [ ] ;
125
121
return await add ( packages , { cwd : root , flags, logging, telemetry } ) ;
126
122
} catch ( err ) {
127
- return throwAndExit ( err ) ;
123
+ return throwAndExit ( cmd , err ) ;
128
124
}
129
125
}
130
126
case 'docs' : {
131
127
try {
132
- telemetry . record ( event . eventCliSession ( { cliCommand : cmd } ) ) ;
128
+ telemetry . record ( event . eventCliSession ( cmd ) ) ;
133
129
return await openInBrowser ( 'https://docs.astro.build/' ) ;
134
130
} catch ( err ) {
135
- return throwAndExit ( err ) ;
131
+ return throwAndExit ( cmd , err ) ;
136
132
}
137
133
}
138
134
case 'telemetry' : {
@@ -142,13 +138,13 @@ export async function cli(args: string[]) {
142
138
const subcommand = flags . _ [ 3 ] ?. toString ( ) ;
143
139
return await telemetryHandler . update ( subcommand , { flags, telemetry } ) ;
144
140
} catch ( err ) {
145
- return throwAndExit ( err ) ;
141
+ return throwAndExit ( cmd , err ) ;
146
142
}
147
143
}
148
144
}
149
145
150
146
const { astroConfig, userConfig } = await openConfig ( { cwd : root , flags, cmd } ) ;
151
- telemetry . record ( event . eventCliSession ( { cliCommand : cmd } , userConfig , flags ) ) ;
147
+ telemetry . record ( event . eventCliSession ( cmd , userConfig , flags ) ) ;
152
148
153
149
// Common CLI Commands:
154
150
// These commands run normally. All commands are assumed to have been handled
@@ -159,15 +155,15 @@ export async function cli(args: string[]) {
159
155
await devServer ( astroConfig , { logging, telemetry } ) ;
160
156
return await new Promise ( ( ) => { } ) ; // lives forever
161
157
} catch ( err ) {
162
- return throwAndExit ( err ) ;
158
+ return throwAndExit ( cmd , err ) ;
163
159
}
164
160
}
165
161
166
162
case 'build' : {
167
163
try {
168
164
return await build ( astroConfig , { logging, telemetry } ) ;
169
165
} catch ( err ) {
170
- return throwAndExit ( err ) ;
166
+ return throwAndExit ( cmd , err ) ;
171
167
}
172
168
}
173
169
@@ -181,21 +177,29 @@ export async function cli(args: string[]) {
181
177
const server = await preview ( astroConfig , { logging, telemetry } ) ;
182
178
return await server . closed ( ) ; // keep alive until the server is closed
183
179
} catch ( err ) {
184
- return throwAndExit ( err ) ;
180
+ return throwAndExit ( cmd , err ) ;
185
181
}
186
182
}
187
183
}
188
184
189
185
// No command handler matched! This is unexpected.
190
- throwAndExit ( new Error ( `Error running ${ cmd } -- no command found.` ) ) ;
186
+ throwAndExit ( cmd , new Error ( `Error running ${ cmd } -- no command found.` ) ) ;
191
187
}
192
188
193
189
/** Display error and exit */
194
- function throwAndExit ( err : unknown ) {
190
+ function throwAndExit ( cmd : string , err : unknown ) {
191
+ let telemetryPromise : Promise < any > ;
195
192
if ( err instanceof z . ZodError ) {
196
193
console . error ( formatConfigErrorMessage ( err ) ) ;
194
+ telemetryPromise = telemetry . record ( eventConfigError ( { cmd, err, isFatal : true } ) ) ;
197
195
} else {
198
- console . error ( formatErrorMessage ( createSafeError ( err ) ) ) ;
196
+ const errorWithMetadata = collectErrorMetadata ( createSafeError ( err ) ) ;
197
+ console . error ( formatErrorMessage ( errorWithMetadata ) ) ;
198
+ telemetryPromise = telemetry . record ( eventError ( { cmd, err : errorWithMetadata , isFatal : true } ) ) ;
199
199
}
200
- process . exit ( 1 ) ;
200
+ // Wait for the telemetry event to send, then exit. Ignore an error.
201
+ telemetryPromise . catch ( ( ) => undefined ) . then ( ( ) => process . exit ( 1 ) ) ;
202
+ // Don't wait too long. Timeout the request faster than usual because the user is waiting.
203
+ // TODO: Investigate using an AbortController once we drop Node v14 support.
204
+ setTimeout ( ( ) => process . exit ( 1 ) , 300 ) ;
201
205
}
0 commit comments