Hooks aren't firing between Impulse modules

An event from one module isn't reaching a handler in another. Either the subscription was never registered, or the handler is throwing on dispatch.

Last updated 20 days ago

Hooks aren't firing between Impulse modules

What you're seeing

A state change in one module should be triggering a handler in another β€” a service termination cleaning up related resources, a quota change updating bundled limits β€” and it isn't. No error in WHMCS, just nothing happens.

Why it happens

Cross-module hooks flow through Core's dispatcher, not directly between modules. On module activation, Core reads hooks_consumed from the manifest and writes one row per hook to mod_impulsecore_hook_subscriptions. When a hook fires, Core looks up every subscription for that event and calls each handler. Two failure modes:

  • The subscription was never written. The producing module fires the event, Core looks up subscriptions, finds none, and the dispatch is a no-op.
  • The subscription exists, but the handler throws when invoked. Core catches the exception and writes an audit entry; the calling code doesn't see it.

Fix

  1. Check the subscription is actually registered.

    SELECT module_slug, hook_name FROM mod_impulsecore_hook_subscriptions ORDER BY module_slug, hook_name;

    Look for the row you expect β€” for example (impulseminio, ServiceTerminate). If it's not there, the consuming module didn't declare that hook in its manifest's hooks_consumed array.

  2. If the row is missing, fix the manifest and re-register.

    Open the consuming module's impulse_module.json and add the hook to hooks_consumed. Then in System Settings β†’ Addon Modules, deactivate and reactivate the module. Core reads the manifest fresh on each activate and inserts the new subscription row.

  3. If the row is present, check the audit log for dispatch failures.

    Open Addons β†’ ImpulseCore β†’ Audit. Filter to action hook.dispatch_failed. The context JSON blob carries the hook name, the failing handler, and the exception message β€” that tells you exactly what threw.

  4. Reproduce the dispatch with debug on.

    Once you have the failing handler identified, trigger the underlying event again (re-fire the service action that should produce the hook). With WHMCS debug mode on, the handler runs with errors visible.

How to confirm it worked

Fire the originating event again β€” terminate a test service, run the action that should produce the hook β€” and check the audit log. You should see one entry for the source event and one or more entries from each consuming module showing they ran their handler. No hook.dispatch_failed entries.

A subtle gotcha

Modules subscribe to hooks by canonical event name, not by WHMCS native hook name. Core re-dispatches WHMCS hooks under canonical names so modules don't have to know which underlying WHMCS hook fired. If a module's hooks_consumed lists a WHMCS-native name that Core doesn't recognise as canonical, the subscription is written but nothing ever matches. Check the module's documentation for the exact event names it should declare.

Related