fix: Codex review round 4 — panic recovery, subtree preservation
- PerformAsync: defer/recover wraps task execution, broadcasts error on panic - Command: preserve existing subtree when overwriting placeholder parent Remaining known architectural: - fs.go TOCTOU (needs openat/fd-based ops) - Global lockMap (needs per-Core registry) - ServiceShutdown goroutine on timeout (inherent to wg.Wait) Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
ee9e715243
commit
61b034335a
2 changed files with 20 additions and 5 deletions
|
|
@ -155,6 +155,15 @@ func (c *Core) Command(path string, command ...Command) Result {
|
|||
cmd.commands = make(map[string]*Command)
|
||||
}
|
||||
|
||||
// Preserve existing subtree when overwriting a placeholder parent
|
||||
if existing, exists := c.commands.commands[path]; exists {
|
||||
for k, v := range existing.commands {
|
||||
if _, has := cmd.commands[k]; !has {
|
||||
cmd.commands[k] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c.commands.commands[path] = cmd
|
||||
|
||||
// Build parent chain — "deploy/to/homelab" creates "deploy" and "deploy/to" if missing
|
||||
|
|
|
|||
|
|
@ -29,6 +29,12 @@ func (c *Core) PerformAsync(t Task) Result {
|
|||
}
|
||||
c.ACTION(ActionTaskStarted{TaskIdentifier: taskID, Task: t})
|
||||
c.wg.Go(func() {
|
||||
defer func() {
|
||||
if rec := recover(); rec != nil {
|
||||
err := E("core.PerformAsync", Sprint("panic: ", rec), nil)
|
||||
c.ACTION(ActionTaskCompleted{TaskIdentifier: taskID, Task: t, Result: nil, Error: err})
|
||||
}
|
||||
}()
|
||||
r := c.PERFORM(t)
|
||||
var err error
|
||||
if !r.OK {
|
||||
|
|
@ -36,11 +42,11 @@ func (c *Core) PerformAsync(t Task) Result {
|
|||
err = e
|
||||
} else {
|
||||
taskType := reflect.TypeOf(t)
|
||||
typeName := "<nil>"
|
||||
if taskType != nil {
|
||||
typeName = taskType.String()
|
||||
}
|
||||
err = E("core.PerformAsync", Join(" ", "no handler found for task type", typeName), nil)
|
||||
typeName := "<nil>"
|
||||
if taskType != nil {
|
||||
typeName = taskType.String()
|
||||
}
|
||||
err = E("core.PerformAsync", Join(" ", "no handler found for task type", typeName), nil)
|
||||
}
|
||||
}
|
||||
c.ACTION(ActionTaskCompleted{TaskIdentifier: taskID, Task: t, Result: r.Value, Error: err})
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue