caughtException);
}
if (jobRecord.isIgnoreException()) {
return;
}
UpdateSpec updateSpec = new UpdateSpec(jobRecord.getRootJobKey());
ExceptionRecord exceptionRecord = new ExceptionRecord(
jobRecord.getRootJobKey(), jobRecord.getKey(), currentRunGUID, caughtException);
updateSpec.getNonTransactionalGroup().includeException(exceptionRecord);
Key exceptionKey = exceptionRecord.getKey();
jobRecord.setExceptionKey(exceptionKey);
if (jobRecord.isCallExceptionHandler() || attemptNumber >= maxAttempts) {
jobRecord.setState(State.STOPPED);
updateSpec.getNonTransactionalGroup().includeJob(jobRecord);
if (jobRecord.isExceptionHandlerSpecified()) {
cancelChildren(jobRecord, null);
executeExceptionHandler(updateSpec, jobRecord, caughtException, false);
} else {
if (null != jobRecord.getExceptionHandlingAncestorKey()) {
cancelChildren(jobRecord, null);
// current job doesn't have an error handler. So just delegate it to the
// nearest ancestor that has one.
Task handleChildExceptionTask = new HandleChildExceptionTask(
jobRecord.getExceptionHandlingAncestorKey(), jobRecord.getKey(),
jobRecord.getQueueSettings());
updateSpec.getFinalTransaction().registerTask(handleChildExceptionTask);
} else {
rootJobRecord.setState(State.STOPPED);
rootJobRecord.setExceptionKey(exceptionKey);
updateSpec.getNonTransactionalGroup().includeJob(rootJobRecord);
}
}
backEnd.save(updateSpec, jobRecord.getQueueSettings());
} else {
jobRecord.setState(State.RETRY);
int backoffFactor = jobRecord.getBackoffFactor();
int backoffSeconds = jobRecord.getBackoffSeconds();
RunJobTask task =
new RunJobTask(jobRecord.getKey(), attemptNumber, jobRecord.getQueueSettings());
task.getQueueSettings().setDelayInSeconds(
backoffSeconds * (long) Math.pow(backoffFactor, attemptNumber));
updateSpec.getFinalTransaction().includeJob(jobRecord);
updateSpec.getFinalTransaction().registerTask(task);
backEnd.saveWithJobStateCheck(updateSpec, jobRecord.getQueueSettings(), jobRecord.getKey(),
State.WAITING_TO_RUN, State.RETRY);
}
}