Business Errors
Introduction
A business error (a BpmnError in BPMN) represents an expected exceptional business condition (for example "credit check rejected" or "document not found"), as opposed to a technical failure such as a database outage or a programming bug. Business errors are meant to be modeled and handled as part of the normal flow of a process or case, rather than causing the whole execution to roll back.
Business errors are engine-neutral: the same concept works in both BPMN and CMMN, and a business error can propagate across process/case boundaries. A business error thrown in a child process invoked from a case (or a child case invoked from a process) that is not handled will bubble up to the calling parent, where it can be caught and handled.
Throwing a business error
There are several ways to throw a business error, depending on where you are modeling.
From a script (engine-neutral, recommended)
The flw.error script API throws a business error that is caught by BPMN error boundary events and CMMN fault sentries, so the same script works unchanged in either engine:
// with an error code and a message
flw.error.throwBusinessError("CREDIT_REJECTED", "Credit check was rejected");
// with just an error code
flw.error.throwBusinessError("CREDIT_REJECTED");
From a script (engine-specific)
If a model is intended to run in only one engine, the engine-specific helper is also available:
flw.bpmn.throwError("CREDIT_REJECTED", "Credit check was rejected");
From a Java delegate
// JavaDelegate
throw new BpmnError("CREDIT_REJECTED", "Credit check was rejected");
Catching a business error in BPMN
A business error is caught in BPMN with an error boundary event attached to an activity (or an error start event in an error event subprocess), matched by error code:

Cross-engine propagation
An unhandled business error propagates up scope by scope, across engine boundaries, until a handler is found.
| Direction | Child scope | Caught in parent by |
|---|---|---|
| BPMN → BPMN | Call activity | Error boundary event on the call activity |
| BPMN → CMMN | Process invoked via a CMMN Process Task | Fault sentry on the Process Task plan item |
| CMMN → BPMN | Case invoked via a BPMN Case Task | Error boundary event on the Case Task |
| CMMN → CMMN | Case Task | Fault sentry on the Case Task plan item |
Multi-level nesting (e.g. CMMN → BPMN → BPMN) works: the error keeps bubbling until handled.
If a business error reaches the root scope with no handler, an exception will be thrown (with the usual exception semantics such as transaction rollback).