Activiti/Activiti · error · ActivitiException

Exception while executing event-listener

Error message

Exception while executing event-listener

What it means

When notifying a single listener, the wrapped ActivitiException('Exception while executing event-listener') is thrown only if that listener's isFailOnException() returns true. The original listener exception is attached as cause. Listeners that return false from isFailOnException() get their exceptions logged and swallowed instead. This wraps arbitrary listener bugs into an ActivitiException propagated out of dispatchEvent.

Solutions

  1. Read the getCause() of the ActivitiException to find the actual listener bug and fix that code.
  2. If failures in this listener should not break the process, override isFailOnException() to return false so exceptions are only logged.
  3. Wrap your listener's onEvent body in its own try-catch to control the failure policy per-exception.
  4. Move heavy/fallible work out of the listener into an async job if it should not affect the transaction.

Example fix

// before
class AuditListener implements ActivitiEventListener {
    public void onEvent(ActivitiEvent e) { writeAudit(e); } // may throw
    public boolean isFailOnException() { return true; }
}
// after
class AuditListener implements ActivitiEventListener {
    public void onEvent(ActivitiEvent e) {
        try { writeAudit(e); } catch (Exception ex) { LOG.error("audit failed", ex); }
    }
    public boolean isFailOnException() { return false; }
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Review listener implementations before registration:
// ensure onEvent is defensive (null-checks, DB error handling)
// and isFailOnException() reflects the intended failure policy.

Type guard

null

Try / catch

try {
    runtimeService.dispatchEvent(event);
} catch (ActivitiException e) {
    LOG.error("Event listener failed", e.getCause());
}

Prevention

When it happens

Trigger: A registered ActivitiEventListener's onEvent(event) throws any Throwable AND the listener overrides isFailOnException() to return true (the default for many engine listeners), causing the wrapped exception to bubble up to the dispatchEvent caller.

Common situations: Business logic in a listener throwing (e.g. NPE on missing process variables, DB errors in a listener that writes audit records); adding a fail-fast listener for events fired inside a transaction, which then rolls back the transaction.

Related errors


AI-assisted analysis of Activiti/Activiti@56435b1a97 (2026-09-09). Data as JSON: /api/errors/b40369902ba4e5ff. Report an issue: GitHub.

Appendix: source

Thrown at activiti-core/activiti-engine/src/main/java/org/activiti/engine/delegate/event/impl/ActivitiEventSupport.java:108

                dispatchEvent(event, listener);
            }
        }

        // Call typed listeners, if any
        List<ActivitiEventListener> typed = typedListeners.get(event.getType());
        if (typed != null && !typed.isEmpty()) {
            for (ActivitiEventListener listener : typed) {
                dispatchEvent(event, listener);
            }
        }
    }

    protected void dispatchEvent(ActivitiEvent event, ActivitiEventListener listener) {
        try {
            listener.onEvent(event);
        } catch (Throwable t) {
            if (listener.isFailOnException()) {
                throw new ActivitiException("Exception while executing event-listener", t);
            } else {
                // Ignore the exception and continue notifying remaining listeners. The listener
                // explicitly states that the exception should not bubble up
                LOG.warn("Exception while executing event-listener, which was ignored", t);
            }
        }
    }

    protected synchronized void addTypedEventListener(ActivitiEventListener listener, ActivitiEventType type) {
        List<ActivitiEventListener> listeners = typedListeners.get(type);
        if (listeners == null) {
            // Add an empty list of listeners for this type
            listeners = new CopyOnWriteArrayList<ActivitiEventListener>();
            typedListeners.put(type, listeners);
        }

        if (!listeners.contains(listener)) {
            listeners.add(listener);

View on GitHub (pinned to 56435b1a97)