77 "github.com/ork-cli/ork/internal/config"
88 "github.com/ork-cli/ork/internal/docker"
99 "github.com/ork-cli/ork/internal/service"
10+ "github.com/ork-cli/ork/internal/ui"
11+ "github.com/ork-cli/ork/pkg/utils"
1012 "github.com/spf13/cobra"
1113)
1214
@@ -29,7 +31,7 @@ var upCmd = &cobra.Command{
2931 Args : cobra .MinimumNArgs (1 ), // Require at least one service name
3032 Run : func (cmd * cobra.Command , args []string ) {
3133 if err := runUp (args ); err != nil {
32- fmt . Printf ( "❌ Error: %v \n " , err )
34+ handleUpError ( err )
3335 return
3436 }
3537 },
@@ -68,30 +70,44 @@ func runUp(serviceNames []string) error {
6870 }
6971 defer func () {
7072 if closeErr := dockerClient .Close (); closeErr != nil {
71- fmt .Printf ( "❌ Error closing Docker client: %v\n " , closeErr )
73+ ui . Warning ( fmt .Sprintf ( "Failed to close Docker client: %v" , closeErr ) )
7274 }
7375 }()
7476
7577 // Resolve dependencies and get services in the correct start order
7678 orderedServices , err := service .ResolveDependencies (cfg .Services , serviceNames )
7779 if err != nil {
78- return fmt .Errorf ("failed to resolve dependencies: %w" , err )
80+ return utils .ServiceError (
81+ "up.dependencies" ,
82+ "Failed to resolve service dependencies" ,
83+ "Check your service dependencies in ork.yml" ,
84+ err ,
85+ )
7986 }
8087
8188 // Create a project network for service communication
8289 ctx := context .Background ()
90+ spinner := ui .ShowSpinner ("Creating project network..." )
8391 networkID , err := dockerClient .CreateNetwork (ctx , cfg .Project )
8492 if err != nil {
85- return fmt .Errorf ("failed to create project network: %w" , err )
93+ spinner .Error ("Failed to create network" )
94+ return utils .NetworkError (
95+ "up.network" ,
96+ "Failed to create project network" ,
97+ "Check if Docker is running and you have permissions" ,
98+ err ,
99+ )
86100 }
87- fmt .Printf ( "🌐 Created network: ork-%s-network\n " , cfg .Project )
101+ spinner . Success ( fmt .Sprintf ( " Created network: ork-%s-network" , cfg .Project ) )
88102
89- // Show startup message
90- fmt .Printf ("✅ Loaded project: %s (version %s)\n " , cfg .Project , cfg .Version )
91- fmt .Printf ("🚀 Starting services: %v\n " , serviceNames )
103+ // Show startup summary
104+ ui .EmptyLine ()
105+ ui .Info (fmt .Sprintf ("Project: %s (v%s)" , ui .Bold (cfg .Project ), cfg .Version ))
106+ ui .Info (fmt .Sprintf ("Starting: %s" , ui .Highlight (fmt .Sprintf ("%v" , serviceNames ))))
92107 if len (orderedServices ) > len (serviceNames ) {
93- fmt .Printf ( "📦 Including dependencies : %v \n " , orderedServices )
108+ ui . Info ( fmt .Sprintf ( "Dependencies : %s" , ui . Dim ( fmt . Sprintf ( "%v " , orderedServices ))) )
94109 }
110+ ui .EmptyLine ()
95111
96112 // Create an orchestrator for parallel service management
97113 orchestrator := service .NewOrchestrator (cfg .Project , dockerClient , networkID )
@@ -106,7 +122,8 @@ func runUp(serviceNames []string) error {
106122 return err
107123 }
108124
109- fmt .Printf ("✅ All services started successfully!\n " )
125+ ui .EmptyLine ()
126+ ui .SuccessBox (fmt .Sprintf ("All services started successfully! %s" , ui .SymbolRocket ))
110127 return nil
111128}
112129
@@ -118,11 +135,21 @@ func runUp(serviceNames []string) error {
118135func loadAndValidateConfig () (* config.Config , error ) {
119136 cfg , err := config .Load ()
120137 if err != nil {
121- return nil , fmt .Errorf ("failed to load config: %w" , err )
138+ return nil , utils .ConfigError (
139+ "up.load" ,
140+ "Failed to load configuration" ,
141+ "Make sure ork.yml exists in the current directory" ,
142+ err ,
143+ )
122144 }
123145
124146 if err := cfg .Validate (); err != nil {
125- return nil , fmt .Errorf ("invalid configuration: %w" , err )
147+ return nil , utils .ConfigError (
148+ "up.validate" ,
149+ "Invalid configuration" ,
150+ "Check your ork.yml for errors" ,
151+ err ,
152+ )
126153 }
127154
128155 return cfg , nil
@@ -136,18 +163,24 @@ func loadAndValidateConfig() (*config.Config, error) {
136163func validateServiceNames (serviceNames []string , cfg * config.Config ) error {
137164 for _ , serviceName := range serviceNames {
138165 if _ , exists := cfg .Services [serviceName ]; ! exists {
139- return fmt .Errorf ("service '%s' not found in ork.yml\n 💡 Available services: %s" ,
140- serviceName , getAvailableServicesList (cfg ))
166+ availableServices := getAvailableServicesList (cfg )
167+ suggestions := utils .FindSuggestions (serviceName , availableServices , 3 )
168+
169+ err := utils .ErrServiceNotFound (serviceName , suggestions )
170+ err .Details = []string {
171+ fmt .Sprintf ("Available services: %s" , ui .Dim (fmt .Sprintf ("%v" , availableServices ))),
172+ }
173+ return err
141174 }
142175 }
143176 return nil
144177}
145178
146- // getAvailableServicesList returns a formatted string of available services
147- func getAvailableServicesList (cfg * config.Config ) string {
148- services := ""
179+ // getAvailableServicesList returns a slice of available service names
180+ func getAvailableServicesList (cfg * config.Config ) [] string {
181+ services := make ([] string , 0 , len ( cfg . Services ))
149182 for name := range cfg .Services {
150- services += name + " "
183+ services = append ( services , name )
151184 }
152185 return services
153186}
@@ -160,7 +193,39 @@ func getAvailableServicesList(cfg *config.Config) string {
160193func createDockerClient () (* docker.Client , error ) {
161194 client , err := docker .NewClient ()
162195 if err != nil {
163- return nil , fmt .Errorf ("failed to create Docker client: %w" , err )
196+ return nil , utils .DockerError (
197+ "up.docker" ,
198+ "Failed to connect to Docker" ,
199+ "Make sure Docker is running. Try 'docker ps' or run 'ork doctor'" ,
200+ err ,
201+ )
164202 }
165203 return client , nil
166204}
205+
206+ // handleUpError formats and displays errors with hints
207+ func handleUpError (err error ) {
208+ if orkErr , ok := err .(* utils.OrkError ); ok {
209+ // Display structured error with hints
210+ ui .Error (orkErr .Message )
211+ if orkErr .Hint != "" {
212+ ui .Hint (orkErr .Hint )
213+ }
214+ if len (orkErr .Details ) > 0 {
215+ ui .EmptyLine ()
216+ for _ , detail := range orkErr .Details {
217+ ui .List (detail )
218+ }
219+ }
220+ if len (orkErr .Suggestions ) > 0 {
221+ ui .EmptyLine ()
222+ ui .Info ("Did you mean:" )
223+ for _ , suggestion := range orkErr .Suggestions {
224+ ui .ListItem (ui .SymbolArrow , ui .Highlight (suggestion ))
225+ }
226+ }
227+ } else {
228+ // Fallback for non-Ork errors
229+ ui .Error (fmt .Sprintf ("Error: %v" , err ))
230+ }
231+ }
0 commit comments