@@ -19,7 +19,7 @@ import { WebSocket } from "partysocket";
1919import { ClientOptions , WebSocket as wsWebSocket } from "ws" ;
2020import { CliApiClient } from "../apiClient.js" ;
2121import { DevCommandOptions } from "../commands/dev.js" ;
22- import { chalkError , chalkTask } from "../utilities/cliOutput.js" ;
22+ import { chalkError , chalkTask , cliLink , prettyError } from "../utilities/cliOutput.js" ;
2323import { resolveDotEnvVars } from "../utilities/dotEnv.js" ;
2424import { eventBus } from "../utilities/eventBus.js" ;
2525import { logger } from "../utilities/logger.js" ;
@@ -189,10 +189,15 @@ class DevWorkerRuntime implements WorkerRuntime {
189189 throw new Error ( "Could not initialize worker" ) ;
190190 }
191191
192- const issues = validateWorkerManifest ( backgroundWorker . manifest ) ;
192+ const validationIssue = validateWorkerManifest ( backgroundWorker . manifest ) ;
193+
194+ if ( validationIssue ) {
195+ prettyError (
196+ generationValidationIssueHeader ( validationIssue ) ,
197+ generateValidationIssueMessage ( validationIssue , backgroundWorker . manifest ! , manifest ) ,
198+ generateValidationIssueFooter ( validationIssue )
199+ ) ;
193200
194- if ( issues . length > 0 ) {
195- issues . forEach ( ( issue ) => logger . error ( issue ) ) ;
196201 stop ( ) ;
197202 return ;
198203 }
@@ -352,22 +357,90 @@ function gatherProcessEnv() {
352357 return Object . fromEntries ( Object . entries ( $env ) . filter ( ( [ key , value ] ) => value !== undefined ) ) ;
353358}
354359
355- function validateWorkerManifest ( manifest : WorkerManifest ) : string [ ] {
356- const issues : string [ ] = [ ] ;
360+ type ValidationIssue =
361+ | {
362+ type : "duplicateTaskId" ;
363+ duplicationTaskIds : string [ ] ;
364+ }
365+ | {
366+ type : "noTasksDefined" ;
367+ } ;
368+
369+ function validateWorkerManifest ( manifest : WorkerManifest ) : ValidationIssue | undefined {
370+ const issues : ValidationIssue [ ] = [ ] ;
357371
358372 if ( ! manifest . tasks || manifest . tasks . length === 0 ) {
359- issues . push ( "No tasks defined. Make sure you are exporting tasks." ) ;
373+ return { type : "noTasksDefined" } ;
360374 }
361375
362376 // Check for any duplicate task ids
363377 const taskIds = manifest . tasks . map ( ( task ) => task . id ) ;
364378 const duplicateTaskIds = taskIds . filter ( ( id , index ) => taskIds . indexOf ( id ) !== index ) ;
365379
366380 if ( duplicateTaskIds . length > 0 ) {
367- issues . push ( createDuplicateTaskIdOutputErrorMessage ( duplicateTaskIds , manifest . tasks ) ) ;
381+ return { type : "duplicateTaskId" , duplicationTaskIds : duplicateTaskIds } ;
382+ }
383+
384+ return undefined ;
385+ }
386+
387+ function generationValidationIssueHeader ( issue : ValidationIssue ) {
388+ switch ( issue . type ) {
389+ case "duplicateTaskId" : {
390+ return `Duplicate task ids detected` ;
391+ }
392+ case "noTasksDefined" : {
393+ return `No tasks exported from your trigger files` ;
394+ }
368395 }
396+ }
369397
370- return issues ;
398+ function generateValidationIssueFooter ( issue : ValidationIssue ) {
399+ switch ( issue . type ) {
400+ case "duplicateTaskId" : {
401+ return cliLink ( "View the task docs" , "https://trigger.dev/docs/tasks/overview" ) ;
402+ }
403+ case "noTasksDefined" : {
404+ return cliLink ( "View the task docs" , "https://trigger.dev/docs/tasks/overview" ) ;
405+ }
406+ }
407+ }
408+
409+ function generateValidationIssueMessage (
410+ issue : ValidationIssue ,
411+ manifest : WorkerManifest ,
412+ buildManifest : BuildManifest
413+ ) {
414+ switch ( issue . type ) {
415+ case "duplicateTaskId" : {
416+ return createDuplicateTaskIdOutputErrorMessage ( issue . duplicationTaskIds , manifest . tasks ) ;
417+ }
418+ case "noTasksDefined" : {
419+ return `
420+ Files:
421+ ${ buildManifest . files . map ( ( file ) => file . entry ) . join ( "\n" ) }
422+
423+ Make sure you have at least one task exported from your trigger files.
424+
425+ You may have defined a task and forgot to add the export statement:
426+
427+ \`\`\`ts
428+ import { task } from "@trigger.dev/sdk/v3";
429+
430+ 👇 Don't forget this
431+ export const myTask = task({
432+ id: "myTask",
433+ async run() {
434+ // Your task logic here
435+ }
436+ });
437+ \`\`\`
438+ ` . replace ( / ^ { 8 } / gm, "" ) ;
439+ }
440+ default : {
441+ return `Unknown validation issue: ${ issue } ` ;
442+ }
443+ }
371444}
372445
373446function createDuplicateTaskIdOutputErrorMessage (
0 commit comments