{"record":{"id":"583213b8f18895d7","repo":"flowable/flowable-engine","slug":"exc-getmessage","errorCode":null,"errorMessage":"${exc.getMessage()}","messagePattern":"\\$\\{exc\\.getMessage\\(\\)\\}","errorType":"exception","errorClass":"ActivitiException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/bpmn/behavior/ServiceTaskDelegateExpressionActivityBehavior.java","lineNumber":133,"sourceCode":"            Throwable cause = exc;\n            BpmnError error = null;\n            while (cause != null) {\n                if (cause instanceof BpmnError) {\n                    error = (BpmnError) cause;\n                    break;\n\n                } else if (cause instanceof RuntimeException) {\n                    if (ErrorPropagation.mapException((RuntimeException) cause, activityExecution, mapExceptions)) {\n                        return;\n                    }\n                }\n                cause = cause.getCause();\n            }\n\n            if (error != null) {\n                ErrorPropagation.propagateError(error, activityExecution);\n            } else {\n                throw new ActivitiException(exc.getMessage(), exc);\n            }\n\n        }\n    }\n\n}\n","sourceCodeStart":115,"sourceCodeEnd":140,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/bpmn/behavior/ServiceTaskDelegateExpressionActivityBehavior.java#L115-L140","documentation":"In ServiceTaskDelegateExpressionActivityBehavior.execute, when the delegate throws an exception that is not a BpmnError (so no error can be propagated), the engine re-throws it as an ActivitiException whose message is the original exception's message, keeping the original as the cause. It is a generic re-wrap of delegate failures.","triggerScenarios":"A delegate resolved via delegateExpression throws a non-BpmnError exception whose walk-back through getCause() finds no BpmnError; e.g. a JavaDelegate's execute() throws RuntimeException, IOException, or NPE during task execution.","commonSituations":"Delegates failing on null process variables, network/DB errors inside the delegate, class-cast issues when reading variables; message may be null when the underlying exception has no message, making logs confusing.","solutions":["Read the 'Caused by' chain for the real exception thrown by the delegate and fix it there","Throw BpmnError from the delegate for business errors so ErrorPropagation can route to error boundary events","Add null-safe message handling/logging in the delegate to avoid 'null' messages","Wrap risky delegate logic (network, parsing) with explicit checks before throwing"],"exampleFix":"// before (delegate)\npublic void execute(DelegateExecution e) {\n    callRemote((String) e.getVariable(\"url\")); // NPE if url is null\n}\n// after\npublic void execute(DelegateExecution e) {\n    String url = (String) e.getVariable(\"url\");\n    if (url == null) {\n        throw new BpmnError(\"MISSING_URL\", \"process variable 'url' is required\");\n    }\n    callRemote(url);\n}","handlingStrategy":"try-catch","validationCode":"String url = (String) execution.getVariable(\"url\");\nif (url == null || url.isEmpty()) {\n    throw new BpmnError(\"MISSING_URL\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    taskService.complete(taskId);\n} catch (org.activiti.engine.ActivitiException e) {\n    Throwable c = e.getCause();\n    // inspect root cause; if business error, route to error handling\n}","preventionTips":["Null-check every process variable consumed by the delegate","Throw BpmnError from delegates for business errors so ErrorPropagation can catch them","Ensure thrown exceptions carry descriptive messages (this wrapper's message mirrors the cause's)","Add a wait-state/error boundary event around service tasks that call external systems"],"tags":["bpmn","service-task","delegate-expression","wrapped-exception"],"backgroundTag":"upstream-api-error","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}