Monorepo for Tangled
0

Configure Feed

Select the types of activity you want to include in your feed.

spindle: categorize error messages with a more generic msg then following details

Signed-off-by: dawn <dawn@tangled.org>

dawn (Jul 1, 2026, 1:17 PM +0300) 6447324b 893e700d

+30 -15
+1 -1
spindle/engines/microvm/agent.go
··· 235 235 } 236 236 } else if p := msg.ActivateConfigResult; p != nil { 237 237 if p.Error != "" { 238 - return nil, fmt.Errorf("activate config failed: %s", p.Error) 238 + return nil, errors.New(p.Error) 239 239 } 240 240 if p.Toplevel == "" { 241 241 return nil, fmt.Errorf("activate config returned empty toplevel")
+16 -7
spindle/engines/microvm/engine.go
··· 187 187 return swf, nil 188 188 } 189 189 190 - func (e *Engine) SetupWorkflow(ctx context.Context, wid models.WorkflowId, wf *models.Workflow, wfLogger models.WorkflowLogger) error { 190 + func (e *Engine) SetupWorkflow(ctx context.Context, wid models.WorkflowId, wf *models.Workflow, wfLogger models.WorkflowLogger) (err error) { 191 191 l := e.l.With("workflow", wid) 192 192 setupStep := Step{name: "microVM setup", kind: models.StepKindSystem} 193 193 194 194 wfLogger.ControlWriter(-1, setupStep, models.StepStatusStart).Write([]byte{0}) 195 195 defer wfLogger.ControlWriter(-1, setupStep, models.StepStatusEnd).Write([]byte{0}) 196 + 197 + category := "Failed to setup VM" 198 + defer func() { 199 + if err != nil { 200 + err = fmt.Errorf("%s:\n%w", category, err) 201 + } 202 + }() 196 203 197 204 state, ok := wf.Data.(*workflowState) 198 205 if !ok || state == nil { ··· 276 283 } 277 284 state.VM = vm 278 285 286 + category = "Failed to connect to agent" 287 + 279 288 acceptCtx, cancelAccept := context.WithTimeout(ctx, agentAcceptTimeout) 280 289 defer cancelAccept() 281 290 conn, err := waitAgentConn(acceptCtx, connCh) ··· 332 341 step := w.Steps[idx] 333 342 if s, ok := step.(Step); ok && s.action == activationStepAction { 334 343 err := e.activateConfig(execCtx, wid, state, s, wfLogger.DataWriter(idx, "stdout")) 335 - return e.classifyStepError(ctx, wid, step, state, stderr, vmExited, err) 344 + return e.classifyStepError(ctx, wid, step, state, stderr, vmExited, "Failed to activate config", err) 336 345 } 337 346 env := []string{ 338 347 "HOME=/workspace", ··· 366 375 Stderr: stderr, 367 376 }) 368 377 if err != nil { 369 - return e.classifyStepError(ctx, wid, step, state, stderr, vmExited, err) 378 + return e.classifyStepError(ctx, wid, step, state, stderr, vmExited, "User step error", err) 370 379 } 371 380 372 381 if exitCode != 0 { 373 382 e.l.Debug("step exited non-zero", "workflow", wid, "step", step.Name(), "exitCode", exitCode) 374 - return engine.ErrWorkflowFailed 383 + return fmt.Errorf("User step error: exited with code %d", exitCode) 375 384 } 376 385 return nil 377 386 } 378 387 379 388 // reads the vm serial logs so we report the tail of that as an error instead of 380 389 // just "guest agent connection lost: EOF" 381 - func (e *Engine) classifyStepError(ctx context.Context, wid models.WorkflowId, step models.Step, state *workflowState, stderr io.Writer, vmExited *atomic.Bool, err error) error { 390 + func (e *Engine) classifyStepError(ctx context.Context, wid models.WorkflowId, step models.Step, state *workflowState, stderr io.Writer, vmExited *atomic.Bool, category string, err error) error { 382 391 if err == nil { 383 392 return nil 384 393 } ··· 397 406 fmt.Fprintln(stderr, reason) 398 407 l.Error(reason, "oom", oom) 399 408 } 400 - return errors.New(reason + "; see workflow logs for serial output") 409 + return fmt.Errorf("%s:\n%w", category, errors.New(reason+"; see workflow logs for serial output")) 401 410 } 402 411 403 412 if errors.Is(err, errGuestTimedOut) || ctx.Err() != nil { ··· 414 423 } else { 415 424 l.Error("step failed", "error", err) 416 425 } 417 - return err 426 + return fmt.Errorf("%s:\n%w", category, err) 418 427 } 419 428 420 429 func (e *Engine) activateConfig(ctx context.Context, wid models.WorkflowId, state *workflowState, step Step, out io.Writer) error {
+13 -7
spindle/engines/nixery/engine.go
··· 195 195 return e.slotter.AcquireWorkflowSlot(ctx, wid, wf) 196 196 } 197 197 198 - func (e *Engine) SetupWorkflow(ctx context.Context, wid models.WorkflowId, wf *models.Workflow, wfLogger models.WorkflowLogger) error { 198 + func (e *Engine) SetupWorkflow(ctx context.Context, wid models.WorkflowId, wf *models.Workflow, wfLogger models.WorkflowLogger) (err error) { 199 199 /// -------------------------INITIAL SETUP------------------------------------------ 200 200 l := e.l.With("workflow", wid) 201 201 l.Info("setting up workflow") ··· 209 209 wfLogger.ControlWriter(setupStepIdx, setupStep, models.StepStatusStart).Write([]byte{0}) 210 210 defer wfLogger.ControlWriter(setupStepIdx, setupStep, models.StepStatusEnd).Write([]byte{0}) 211 211 212 + defer func() { 213 + if err != nil { 214 + err = fmt.Errorf("Failed to setup container:\n%w", err) 215 + } 216 + }() 217 + 212 218 /// -------------------------NETWORK CREATION--------------------------------------- 213 - _, err := e.docker.NetworkCreate(ctx, networkName(wid), network.CreateOptions{ 219 + _, err = e.docker.NetworkCreate(ctx, networkName(wid), network.CreateOptions{ 214 220 Driver: "bridge", 215 221 }) 216 222 if err != nil { ··· 402 408 Env: envs, 403 409 }) 404 410 if err != nil { 405 - return fmt.Errorf("creating exec: %w", err) 411 + return fmt.Errorf("User step error:\ncreating exec: %w", err) 406 412 } 407 413 408 414 // start tailing logs in background ··· 434 440 435 441 execInspectResp, err := e.docker.ContainerExecInspect(ctx, mkExecResp.ID) 436 442 if err != nil { 437 - return err 443 + return fmt.Errorf("User step error:\n%w", err) 438 444 } 439 445 440 446 if execInspectResp.ExitCode != 0 { 441 447 inspectResp, err := e.docker.ContainerInspect(ctx, addl.container) 442 448 if err != nil { 443 - return err 449 + return fmt.Errorf("User step error:\n%w", err) 444 450 } 445 451 446 452 e.l.Error("workflow failed!", "workflow_id", wid.String(), "exit_code", execInspectResp.ExitCode, "oom_killed", inspectResp.State.OOMKilled) 447 453 448 454 if inspectResp.State.OOMKilled { 449 - return ErrOOMKilled 455 + return fmt.Errorf("User step error:\n%w", ErrOOMKilled) 450 456 } 451 - return engine.ErrWorkflowFailed 457 + return fmt.Errorf("User step error: exited with code %d", execInspectResp.ExitCode) 452 458 } 453 459 454 460 return nil