{"record":{"id":"f620a09f377ec86e","repo":"flowable/flowable-engine","slug":"unable-to-handle-exception","errorCode":null,"errorMessage":"Unable to handle exception ","messagePattern":"Unable to handle exception ","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/asyncexecutor/ExecuteAsyncRunnable.java","lineNumber":305,"sourceCode":"                    });\n                }\n            });\n            \n            return;\n        }\n        \n        for (AsyncRunnableExecutionExceptionHandler asyncRunnableExecutionExceptionHandler : asyncRunnableExecutionExceptionHandlers) {\n            if (asyncRunnableExecutionExceptionHandler.handleException(this.jobServiceConfiguration, this.job, exception)) {\n                \n                // Needs to run in a separate transaction as the original transaction has been marked for rollback\n                unlockJobIfNeeded();\n                \n                return;\n            }\n        }\n        \n        LOGGER.error(\"Unable to handle exception {} for job {}.\", exception, job);\n        throw new FlowableException(\"Unable to handle exception \" + exception.getMessage() + \" for \" + job + \".\", exception);\n    }\n\n}\n","sourceCodeStart":287,"sourceCodeEnd":309,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/asyncexecutor/ExecuteAsyncRunnable.java#L287-L309","documentation":"When a job fails, ExecuteAsyncRunnable.handleFailedJob records the failure (retries, exception stacktrace, deadletter). If handling itself throws (e.g. the failure-recording command fails, or no exception handler applied), the runnable logs 'Unable to handle exception' and rethrows a wrapping FlowableException. This means the original job error could not be persisted, so retry accounting is incomplete.","triggerScenarios":"executeJob catches the job's original exception and calls handleFailedJob, but the failure-handling path (decrementing retries, saving the exception stacktrace, moving to deadletter) throws — e.g. DB constraint issues, transaction problems, or a null original exception message path — and ExecuteAsyncRunnable.java:305 wraps it.","commonSituations":"Database outages or lock contention while persisting job failure info; custom JobExceptionHandler throwing; serializer failing to persist the exception stacktrace column; jobs deleted concurrently by another node while being failed.","solutions":["Inspect the 'cause' of this exception — it hides the root failure that prevented failure-recording; fix that underlying issue first.","Check database connectivity/constraints on ACT_RU_JOB / ACT_RU_DEADLETTER_JOB during failure handling.","Verify the job still exists (not concurrently deleted) when failure handling runs; guard multi-node deployments.","Ensure custom exception handlers (JobExceptionHandler) do not throw."],"exampleFix":"// before\n// failure handling throws, job lost without retry accounting\ntry {\n  jobManager.execute(job);\n} catch (Exception e) {\n  // swallow\n}\n\n// after\ntry {\n  jobManager.execute(job);\n} catch (FlowableException e) {\n  LOGGER.error(\"Job execution and failure handling failed\", e.getCause() != null ? e.getCause() : e);\n  // inspect cause: DB state / handler errors\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  jobManager.execute(job);\n} catch (FlowableException e) {\n  Throwable root = e.getCause() != null ? e.getCause() : e;\n  LOGGER.error(\"Job failure handling failed; root cause: {}\", root, root);\n  // inspect root: DB state, concurrent deletion, serializer errors\n}","preventionTips":["Always log and inspect the cause chain of this error.","Monitor DB health on job tables; failures here often follow DB outages.","Avoid concurrent deletion of jobs while the executor processes them in clustered setups.","Keep custom JobExceptionHandler implementations exception-free."],"tags":["flowable","job-failure","exception-handling","database"],"backgroundTag":"internal-invariant-violation","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"}