-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Description
Which version of ElasticJob did you use?
Source code analysis based on the latest version (3.x).
Expected behavior
When an unhandled exception occurs during the job execution (jobItemExecutor.process), the job execution status in the registry center should correctly reflect a failure.
Even if a specific JobErrorHandler is configured (e.g., the default LogJobErrorHandler), the core executor logic should ensure that the scheduler does not misinterpret the job completion as "successful" when it actually failed with an exception. The registerJobCompleted call should ideally be aware of the execution result (Success vs. Failure).
Actual behavior
In ElasticJobExecutor.java, the process method captures all Throwables within a try-catch block. The exception handling is delegated to the configured JobErrorHandler.
If the user uses the default LogJobErrorHandler (which only logs the error and returns), the execution flow continues out of the catch block and eventually calls jobFacade.registerJobCompleted(shardingContexts).
This leads to a scenario where a job logic threw an exception (Failure), but the registerJobCompleted method might signal a successful completion to the registry center (depending on how registerJobCompleted handles the state internally). This inconsistent state could potentially affect misfire handling or dependent job flows, causing "false success" signals.
Reason / Code Reference
In org.apache.shardingsphere.elasticjob.kernel.executor.ElasticJobExecutor:
// Logic inside process(...) method
try {
jobItemExecutor.process(elasticJob, jobConfig, jobFacade.getJobRuntimeService(), shardingContexts.createShardingContext(item));
completeEvent = startEvent.executionSuccess();
// ...
} catch (final Throwable cause) {
// 1. The event is posted as failure locally
completeEvent = startEvent.executionFailure(ExceptionUtils.transform(cause));
jobFacade.postJobExecutionEvent(completeEvent);
itemErrorMessages.put(item, ExceptionUtils.transform(cause));
// 2. Delegate to ErrorHandler.
// If this is LogJobErrorHandler, it just logs and swallows the exception.
JobErrorHandler jobErrorHandler = jobErrorHandlerReloader.getJobErrorHandler();
jobErrorHandler.handleException(jobConfig.getJobName(), cause);
}
// 3. The flow continues to finally block or subsequent logic (in the outer execute method)
// which triggers registerJobCompleted blindly.
// jobFacade.registerJobCompleted(shardingContexts);
Suggestion
Review the ElasticJobExecutor logic to ensure that jobFacade.registerJobCompleted(shardingContexts) respects the actual execution result (success or failure) of the sharding items, rather than relying solely on the fact that the method execution finished.