diff --git a/pkg/events/service.go b/pkg/events/service.go index 3a8745f9..1018f186 100644 --- a/pkg/events/service.go +++ b/pkg/events/service.go @@ -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) diff --git a/pkg/events/service_test.go b/pkg/events/service_test.go index 9c375020..234c0a53 100644 --- a/pkg/events/service_test.go +++ b/pkg/events/service_test.go @@ -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) {