From b2d0deb99bff98210a318a7c536ee6e677169edc Mon Sep 17 00:00:00 2001 From: Snider Date: Fri, 20 Mar 2026 15:49:33 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20AX=20audit=20round=203=20=E2=80=94=208?= =?UTF-8?q?=20violations=20resolved?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - core.go: Result{Value: wrapped} → Result{wrapped, false} (explicit failure) - error.go: fmt.Sprint → Sprint wrapper, removed fmt import - fs.go: Stat/Open propagate validatePath failures (return vp) - lock.go: Startables/Stoppables return Result - task.go: PerformAsync returns Result - runtime.go: updated to unwrap Result from Startables/Stoppables Co-Authored-By: Virgil --- pkg/core/core.go | 4 ++-- pkg/core/error.go | 3 +-- pkg/core/fs.go | 4 ++-- pkg/core/lock.go | 12 ++++++------ pkg/core/runtime.go | 28 +++++++++++++++++----------- pkg/core/task.go | 6 +++--- tests/lock_test.go | 8 ++++++-- tests/service_test.go | 8 ++++++-- tests/task_test.go | 9 ++++++--- 9 files changed, 49 insertions(+), 33 deletions(-) diff --git a/pkg/core/core.go b/pkg/core/core.go index 7f78749..9252c61 100644 --- a/pkg/core/core.go +++ b/pkg/core/core.go @@ -65,7 +65,7 @@ func (c *Core) LogError(err error, op, msg string) Result { if wrapped == nil { return Result{OK: true} } - return Result{Value: wrapped} + return Result{wrapped, false} } // LogWarn logs a warning and returns a Result with the wrapped error. @@ -74,7 +74,7 @@ func (c *Core) LogWarn(err error, op, msg string) Result { if wrapped == nil { return Result{OK: true} } - return Result{Value: wrapped} + return Result{wrapped, false} } // Must logs and panics if err is not nil. diff --git a/pkg/core/error.go b/pkg/core/error.go index 399288d..d66e570 100644 --- a/pkg/core/error.go +++ b/pkg/core/error.go @@ -9,7 +9,6 @@ package core import ( "encoding/json" "errors" - "fmt" "iter" "maps" "os" @@ -314,7 +313,7 @@ func (h *ErrorPanic) Recover() { err, ok := r.(error) if !ok { - err = NewError(fmt.Sprint("panic: ", r)) + err = NewError(Sprint("panic: ", r)) } report := CrashReport{ diff --git a/pkg/core/fs.go b/pkg/core/fs.go index 47a6d85..de65c52 100644 --- a/pkg/core/fs.go +++ b/pkg/core/fs.go @@ -185,7 +185,7 @@ func (m *Fs) List(p string) Result { func (m *Fs) Stat(p string) Result { vp := m.validatePath(p) if !vp.OK { - return Result{} + return vp } return Result{}.Result(os.Stat(vp.Value.(string))) } @@ -194,7 +194,7 @@ func (m *Fs) Stat(p string) Result { func (m *Fs) Open(p string) Result { vp := m.validatePath(p) if !vp.OK { - return Result{} + return vp } return Result{}.Result(os.Open(vp.Value.(string))) } diff --git a/pkg/core/lock.go b/pkg/core/lock.go index 3f0fb31..8e96994 100644 --- a/pkg/core/lock.go +++ b/pkg/core/lock.go @@ -60,9 +60,9 @@ func (c *Core) LockApply(name ...string) { } // Startables returns services that have an OnStart function. -func (c *Core) Startables() []*Service { +func (c *Core) Startables() Result { if c.services == nil { - return nil + return Result{} } c.Lock("srv").Mu.RLock() defer c.Lock("srv").Mu.RUnlock() @@ -72,13 +72,13 @@ func (c *Core) Startables() []*Service { out = append(out, svc) } } - return out + return Result{out, true} } // Stoppables returns services that have an OnStop function. -func (c *Core) Stoppables() []*Service { +func (c *Core) Stoppables() Result { if c.services == nil { - return nil + return Result{} } c.Lock("srv").Mu.RLock() defer c.Lock("srv").Mu.RUnlock() @@ -88,5 +88,5 @@ func (c *Core) Stoppables() []*Service { out = append(out, svc) } } - return out + return Result{out, true} } diff --git a/pkg/core/runtime.go b/pkg/core/runtime.go index d723e5a..738b38d 100644 --- a/pkg/core/runtime.go +++ b/pkg/core/runtime.go @@ -33,13 +33,16 @@ func (r *ServiceRuntime[T]) Config() *Config { return r.core.Config() } // ServiceStartup runs OnStart for all registered services that have one. func (c *Core) ServiceStartup(ctx context.Context, options any) Result { - for _, s := range c.Startables() { - if err := ctx.Err(); err != nil { - return Result{err, false} - } - r := s.OnStart() - if !r.OK { - return r + startables := c.Startables() + if startables.OK { + for _, s := range startables.Value.([]*Service) { + if err := ctx.Err(); err != nil { + return Result{err, false} + } + r := s.OnStart() + if !r.OK { + return r + } } } c.ACTION(ActionServiceStartup{}) @@ -50,11 +53,14 @@ func (c *Core) ServiceStartup(ctx context.Context, options any) Result { func (c *Core) ServiceShutdown(ctx context.Context) Result { c.shutdown.Store(true) c.ACTION(ActionServiceShutdown{}) - for _, s := range c.Stoppables() { - if err := ctx.Err(); err != nil { - return Result{err, false} + stoppables := c.Stoppables() + if stoppables.OK { + for _, s := range stoppables.Value.([]*Service) { + if err := ctx.Err(); err != nil { + return Result{err, false} + } + s.OnStop() } - s.OnStop() } done := make(chan struct{}) go func() { diff --git a/pkg/core/task.go b/pkg/core/task.go index 7ad1a40..c984271 100644 --- a/pkg/core/task.go +++ b/pkg/core/task.go @@ -19,9 +19,9 @@ type TaskState struct { } // PerformAsync dispatches a task in a background goroutine. -func (c *Core) PerformAsync(t Task) string { +func (c *Core) PerformAsync(t Task) Result { if c.shutdown.Load() { - return "" + return Result{} } taskID := Concat("task-", strconv.FormatUint(c.taskIDCounter.Add(1), 10)) if tid, ok := t.(TaskWithID); ok { @@ -40,7 +40,7 @@ func (c *Core) PerformAsync(t Task) string { } c.ACTION(ActionTaskCompleted{TaskID: taskID, Task: t, Result: r.Value, Error: err}) }) - return taskID + return Result{taskID, true} } // Progress broadcasts a progress update for a background task. diff --git a/tests/lock_test.go b/tests/lock_test.go index aa60f23..54dc200 100644 --- a/tests/lock_test.go +++ b/tests/lock_test.go @@ -41,11 +41,15 @@ func TestLockEnable_Good(t *testing.T) { func TestStartables_Good(t *testing.T) { c := New() c.Service("s", Service{OnStart: func() Result { return Result{OK: true} }}) - assert.Len(t, c.Startables(), 1) + r := c.Startables() + assert.True(t, r.OK) + assert.Len(t, r.Value.([]*Service), 1) } func TestStoppables_Good(t *testing.T) { c := New() c.Service("s", Service{OnStop: func() Result { return Result{OK: true} }}) - assert.Len(t, c.Stoppables(), 1) + r := c.Stoppables() + assert.True(t, r.OK) + assert.Len(t, r.Value.([]*Service), 1) } diff --git a/tests/service_test.go b/tests/service_test.go index 1cbb74e..948217d 100644 --- a/tests/service_test.go +++ b/tests/service_test.go @@ -63,12 +63,16 @@ func TestService_Lifecycle_Good(t *testing.T) { OnStop: func() Result { stopped = true; return Result{OK: true} }, }) - startables := c.Startables() + sr := c.Startables() + assert.True(t, sr.OK) + startables := sr.Value.([]*Service) assert.Len(t, startables, 1) startables[0].OnStart() assert.True(t, started) - stoppables := c.Stoppables() + tr := c.Stoppables() + assert.True(t, tr.OK) + stoppables := tr.Value.([]*Service) assert.Len(t, stoppables, 1) stoppables[0].OnStop() assert.True(t, stopped) diff --git a/tests/task_test.go b/tests/task_test.go index df1071d..54f728e 100644 --- a/tests/task_test.go +++ b/tests/task_test.go @@ -20,10 +20,12 @@ func TestPerformAsync_Good(t *testing.T) { mu.Lock() result = "done" mu.Unlock() - return Result{Value: "completed", OK: true} + return Result{"completed", true} }) - taskID := c.PerformAsync("work") + r := c.PerformAsync("work") + assert.True(t, r.OK) + taskID := r.Value.(string) assert.NotEmpty(t, taskID) time.Sleep(100 * time.Millisecond) @@ -39,7 +41,8 @@ func TestPerformAsync_Progress_Good(t *testing.T) { return Result{OK: true} }) - taskID := c.PerformAsync("work") + r := c.PerformAsync("work") + taskID := r.Value.(string) c.Progress(taskID, 0.5, "halfway", "work") }