Harden events service nil platform handling
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run

This commit is contained in:
Snider 2026-04-17 19:18:53 +01:00
parent e4454bc707
commit 908eab58b6
2 changed files with 50 additions and 0 deletions

View file

@ -34,6 +34,9 @@ func (s *Service) OnStartup(_ context.Context) core.Result {
if err := validateEventName("events.emit", t.Name); err != nil {
return core.Result{Value: err, OK: false}
}
if err := s.requirePlatform("events.emit"); err != nil {
return core.Result{Value: err, OK: false}
}
cancelled := s.platform.Emit(t.Name, t.Data)
return core.Result{Value: cancelled, OK: true}
})
@ -42,6 +45,9 @@ func (s *Service) OnStartup(_ context.Context) core.Result {
if err := validateEventName("events.on", t.Name); err != nil {
return core.Result{Value: err, OK: false}
}
if err := s.requirePlatform("events.on"); err != nil {
return core.Result{Value: err, OK: false}
}
cancel := s.platform.On(t.Name, func(event *CustomEvent) {
_ = s.Core().ACTION(ActionEventFired{Event: *event})
})
@ -58,6 +64,9 @@ func (s *Service) OnStartup(_ context.Context) core.Result {
if err := validateEventName("events.off", t.Name); err != nil {
return core.Result{Value: err, OK: false}
}
if err := s.requirePlatform("events.off"); err != nil {
return core.Result{Value: err, OK: false}
}
s.platform.Off(t.Name)
s.mu.Lock()
for _, cancel := range s.listeners[t.Name] {
@ -71,6 +80,13 @@ func (s *Service) OnStartup(_ context.Context) core.Result {
return core.Result{OK: true}
}
func (s *Service) requirePlatform(method string) error {
if s == nil || s.platform == nil {
return coreerr.E(method, "event platform unavailable", nil)
}
return nil
}
func validateEventName(method, name string) error {
if strings.TrimSpace(name) == "" {
return coreerr.E(method, "event name must not be empty", nil)

View file

@ -315,6 +315,40 @@ func TestTaskEmit_NoService_Bad(t *testing.T) {
assert.False(t, r.OK)
}
func TestTaskEmit_PlatformUnavailable_Bad(t *testing.T) {
c := core.New(
core.WithService(Register(nil)),
core.WithServiceLock(),
)
require.True(t, c.ServiceStartup(context.Background(), nil).OK)
svc := core.MustServiceFor[*Service](c, "events")
r := taskRun(c, "events.emit", TaskEmit{Name: "user:login"})
require.False(t, r.OK)
err, ok := r.Value.(error)
require.True(t, ok)
require.Error(t, err)
assert.Contains(t, err.Error(), "event platform unavailable")
r = taskRun(c, "events.on", TaskOn{Name: "user:login"})
require.False(t, r.OK)
err, ok = r.Value.(error)
require.True(t, ok)
require.Error(t, err)
assert.Contains(t, err.Error(), "event platform unavailable")
r = taskRun(c, "events.off", TaskOff{Name: "user:login"})
require.False(t, r.OK)
err, ok = r.Value.(error)
require.True(t, ok)
require.Error(t, err)
assert.Contains(t, err.Error(), "event platform unavailable")
require.NotPanics(t, func() {
assert.True(t, svc.OnShutdown(context.Background()).OK)
})
}
// --- Ugly path tests ---
func TestTaskOff_NeverRegistered_Ugly(t *testing.T) {