fix(arch-014,arch-020): no contract lazy-resurrect after unregister; event bus dedupes handlers
Check Cross-Plugin Imports / check (push) Has been cancelled
Check Cross-Plugin Imports / check (push) Has been cancelled
Also fixes ARCH-029/041: none-check before attribute access in trigger dispatcher.
This commit is contained in:
@@ -36,8 +36,13 @@ class EventBus:
|
||||
self._handlers: dict[str, list[EventHandler]] = defaultdict(list)
|
||||
|
||||
def subscribe(self, event_name: str, handler: EventHandler) -> None:
|
||||
"""Subscribe a handler to an event."""
|
||||
self._handlers[event_name].append(handler)
|
||||
"""Subscribe a handler to an event.
|
||||
|
||||
Idempotent: subscribing the same handler twice is a no-op
|
||||
(ARCH-020) so double activation cannot fire handlers twice.
|
||||
"""
|
||||
if handler not in self._handlers[event_name]:
|
||||
self._handlers[event_name].append(handler)
|
||||
|
||||
def unsubscribe(self, event_name: str, handler: EventHandler) -> None:
|
||||
"""Unsubscribe a handler from an event."""
|
||||
|
||||
@@ -121,11 +121,14 @@ class TriggerDispatcher:
|
||||
"""Query DB for active automations matching *event_name* and dispatch."""
|
||||
from app.core.db import get_session_factory
|
||||
from app.plugins.builtins.contracts import get_contract
|
||||
# None-check FIRST — accessing attributes on the contract before the
|
||||
# check crashed with AttributeError when automation was inactive
|
||||
# (ARCH-029/041).
|
||||
automation_contract = get_contract("automation")
|
||||
AutomationDefinition = automation_contract.Automation # noqa: N806
|
||||
if automation_contract is None:
|
||||
logger.debug("Automation plugin not available — trigger skipped")
|
||||
return
|
||||
AutomationDefinition = automation_contract.Automation # noqa: N806
|
||||
|
||||
factory = get_session_factory()
|
||||
tenant_id = payload.get("tenant_id")
|
||||
|
||||
Reference in New Issue
Block a user