@@ -17,12 +17,25 @@ import {
1717 collectCreateAddonSetupContext ,
1818 executeCreateAddonSetupContext ,
1919} from "../tasks/setup-addons" ;
20+ import {
21+ trackCreateCompleted ,
22+ trackCreateFailed ,
23+ type CreateTelemetryFailureStage ,
24+ } from "../telemetry" ;
2025import { getCreatePrismaIntro } from "../ui/branding" ;
2126
2227const DEFAULT_PROJECT_NAME = "my-app" ;
2328const DEFAULT_TEMPLATE : CreateTemplate = "hono" ;
2429const DEFAULT_SCHEMA_PRESET : SchemaPreset = "basic" ;
2530
31+ type ExecuteCreateContextResult =
32+ | { ok : true }
33+ | {
34+ ok : false ;
35+ stage : CreateTelemetryFailureStage ;
36+ error ?: unknown ;
37+ } ;
38+
2639function toPackageName ( projectName : string ) : string {
2740 return (
2841 projectName
@@ -148,19 +161,59 @@ async function inspectTargetPath(targetPath: string): Promise<CreateTargetPathSt
148161}
149162
150163export async function runCreateCommand ( rawInput : CreateCommandInput = { } ) : Promise < void > {
164+ const startedAt = Date . now ( ) ;
165+ let input : CreateCommandInput = { } ;
166+ let context : CreatePromptContext | undefined ;
167+ let failureStage : CreateTelemetryFailureStage = "validate_input" ;
168+
151169 try {
152- const input = CreateCommandInputSchema . parse ( rawInput ) ;
170+ input = CreateCommandInputSchema . parse ( rawInput ) ;
153171
154172 intro ( getCreatePrismaIntro ( ) ) ;
155173
156- const context = await collectCreateContext ( input ) ;
174+ failureStage = "collect_context" ;
175+ context = await collectCreateContext ( input ) ;
157176 if ( ! context ) {
158177 return ;
159178 }
160179
161- await executeCreateContext ( context ) ;
180+ failureStage = "unknown" ;
181+ const executionResult = await executeCreateContext ( context ) ;
182+ if ( ! executionResult . ok ) {
183+ if ( executionResult . error ) {
184+ cancel (
185+ `Create command failed: ${
186+ executionResult . error instanceof Error
187+ ? executionResult . error . message
188+ : String ( executionResult . error )
189+ } `,
190+ ) ;
191+ }
192+
193+ await trackCreateFailed ( {
194+ input,
195+ context,
196+ durationMs : Date . now ( ) - startedAt ,
197+ error : executionResult . error ,
198+ stage : executionResult . stage ,
199+ } ) ;
200+ return ;
201+ }
202+
203+ await trackCreateCompleted ( {
204+ input,
205+ context,
206+ durationMs : Date . now ( ) - startedAt ,
207+ } ) ;
162208 } catch ( error ) {
163209 cancel ( `Create command failed: ${ error instanceof Error ? error . message : String ( error ) } ` ) ;
210+ await trackCreateFailed ( {
211+ input,
212+ context,
213+ durationMs : Date . now ( ) - startedAt ,
214+ error,
215+ stage : failureStage ,
216+ } ) ;
164217 }
165218}
166219
@@ -230,7 +283,9 @@ async function collectCreateContext(
230283 } ;
231284}
232285
233- async function executeCreateContext ( context : CreatePromptContext ) : Promise < void > {
286+ async function executeCreateContext (
287+ context : CreatePromptContext ,
288+ ) : Promise < ExecuteCreateContextResult > {
234289 const scaffoldSpinner = spinner ( ) ;
235290 scaffoldSpinner . start ( `Scaffolding ${ context . template } project...` ) ;
236291 try {
@@ -245,8 +300,11 @@ async function executeCreateContext(context: CreatePromptContext): Promise<void>
245300 scaffoldSpinner . stop ( "Project files scaffolded." ) ;
246301 } catch ( error ) {
247302 scaffoldSpinner . stop ( "Could not scaffold project files." ) ;
248- cancel ( error instanceof Error ? error . message : String ( error ) ) ;
249- return ;
303+ return {
304+ ok : false ,
305+ stage : "scaffold_template" ,
306+ error,
307+ } ;
250308 }
251309
252310 if (
@@ -261,17 +319,42 @@ async function executeCreateContext(context: CreatePromptContext): Promise<void>
261319
262320 const cdStep = `- cd ${ formatPathForDisplay ( context . targetDirectory ) } ` ;
263321 if ( context . addonSetupContext ) {
264- await executeCreateAddonSetupContext ( {
265- context : context . addonSetupContext ,
266- packageManager : context . prismaSetupContext . packageManager ,
322+ try {
323+ await executeCreateAddonSetupContext ( {
324+ context : context . addonSetupContext ,
325+ packageManager : context . prismaSetupContext . packageManager ,
326+ projectDir : context . targetDirectory ,
327+ verbose : context . prismaSetupContext . verbose ,
328+ } ) ;
329+ } catch ( error ) {
330+ return {
331+ ok : false ,
332+ stage : "addons" ,
333+ error,
334+ } ;
335+ }
336+ }
337+
338+ try {
339+ const prismaSetupResult = await executePrismaSetupContext ( context . prismaSetupContext , {
340+ prependNextSteps : [ cdStep ] ,
267341 projectDir : context . targetDirectory ,
268- verbose : context . prismaSetupContext . verbose ,
342+ includeDevNextStep : true ,
269343 } ) ;
344+
345+ if ( ! prismaSetupResult ) {
346+ return {
347+ ok : false ,
348+ stage : "prisma_setup" ,
349+ } ;
350+ }
351+ } catch ( error ) {
352+ return {
353+ ok : false ,
354+ stage : "prisma_setup" ,
355+ error,
356+ } ;
270357 }
271358
272- await executePrismaSetupContext ( context . prismaSetupContext , {
273- prependNextSteps : [ cdStep ] ,
274- projectDir : context . targetDirectory ,
275- includeDevNextStep : true ,
276- } ) ;
359+ return { ok : true } ;
277360}
0 commit comments