Exception handling in BPM / BAW works at four levels; a robust design uses all of them deliberately:
- Inside a script: try / catch for expected failures (parsing, optional lookups); rethrow with context.
- In a service flow: attach an error intermediate event to a step (integration, script, nested service) - it catches errors from that step and continues on the error path; map the error data to a variable (for example tw.local.err) through the event's data mapping; end the flow with an Error end event to propagate a typed error to the caller.
- In a BPD: error boundary events on activities (catch a specific error code or all), an event sub-process with an error start event for process-wide handling, and the "Failed" instance state as the last resort: a failed activity leaves the instance in Failed so that operations can retry it (Process Admin / REST action=retry) after fixing the cause - design for retry (idempotent integrations).
- In a CSHS: error events on script and service steps, a coach that shows the message, and the global error handler (question 2887).
// service flow script: fail with a typed error the BPD can catch by code
var e = new Error("Credit service unavailable");
e.errorCode = "CREDIT-503"; // BPD error boundary event: catch "CREDIT-503" -> retry path / escalate
throw e;
// BPD error boundary (all errors): map error data to tw.local.err, then a script:
tw.local.incident = { message: tw.local.err.errorMessage, code: tw.local.err.errorCode, step: "Check credit", piid: tw.system.currentProcessInstanceID };
// -> "Create incident" service, then a user task "Handle exception" with a Retry / Skip decision that loops backPrinciples: catch where you can do something (retry, compensate, route to a human), let everything else fail loudly (Failed state + alert), log the instance id and step with every error, keep integrations idempotent so that retry is safe, and put the reusable parts (log, incident, notify) into a toolkit so that every app handles errors the same way.
References