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
- Read the getCause() of the ActivitiException to find the actual listener bug and fix that code.
- If failures in this listener should not break the process, override isFailOnException() to return false so exceptions are only logged.
- Wrap your listener's onEvent body in its own try-catch to control the failure policy per-exception.
- 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
- Read the cause chain to find the real listener exception
- Return false from isFailOnException() for best-effort listeners
- Wrap fallible listener logic in its own try-catch
- Keep listeners lightweight; offload heavy work to async jobs
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
- Job failed
- businessCalendars can not be null
- Cannot combine onlyTimers() with onlyMessages() in the same…
- Cannot combine onlyTimers() with onlyMessages() in the same…
- Cannot find process definition with id
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)