elunez/eladmin · error · BadRequestException

更新定时任务失败

Error message

更新定时任务失败

What it means

QuartzManage.updateJobCron rebuilds the CronTrigger for a job and calls scheduler.rescheduleJob(triggerKey, trigger); any exception in that flow (missing trigger, schedule build failure, reschedule failure) is logged and rethrown as BadRequestException '更新定时任务失败'. Because callers are @Transactional, the already-saved job row update rolls back.

Source

Thrown at eladmin-system/src/main/java/me/zhengjie/modules/quartz/utils/QuartzManage.java:102

            // 如果不存在则创建一个定时任务
            if(trigger == null){
                addJob(quartzJob);
                trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            }
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(quartzJob.getCronExpression());
            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
            //重置启动时间
            ((CronTriggerImpl)trigger).setStartTime(new Date());
            trigger.getJobDataMap().put(QuartzJob.JOB_KEY,quartzJob);

            scheduler.rescheduleJob(triggerKey, trigger);
            // 暂停任务
            if (quartzJob.getIsPause()) {
                pauseJob(quartzJob);
            }
        } catch (Exception e){
            log.error("更新定时任务失败", e);
            throw new BadRequestException("更新定时任务失败");
        }

    }

    /**
     * 删除一个job
     * @param quartzJob /
     */
    public void deleteJob(QuartzJob quartzJob){
        try {
            JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId());
            scheduler.pauseJob(jobKey);
            scheduler.deleteJob(jobKey);
        } catch (Exception e){
            log.error("删除定时任务失败", e);
            throw new BadRequestException("删除定时任务失败");
        }
    }

View on GitHub (pinned to 55fbf70595)

Solutions

  1. Check the logged stack trace for the true exception (commonly ObjectDoesNotExistException for the trigger key).
  2. If the trigger is missing, recreate the job via the UI (delete + re-add) so addJob registers a fresh trigger, or call the resume/run path which lazily calls addJob when trigger == null.
  3. Keep Quartz job store and the business DB consistent — when wiping quartz tables, also clear quartz_job rows.
Defensive patterns

Strategy: try-catch

Validate before calling

// detect trigger-drift before updating
TriggerKey tk = TriggerKey.triggerKey("JOB_NAME" + job.getId());
if (scheduler.getTrigger(tk) == null) {
    // recreate instead of reschedule
    quartzManage.addJob(job);
}

Try / catch

try { quartzJobService.update(job); } catch (BadRequestException e) { if ("更新定时任务失败".equals(e.getMessage())) { log.error("reschedule failed", e); quartzManage.addJob(job); // rebuild trigger } else throw e; }

Prevention

When it happens

Trigger: PUT /api/quartz/jobs where the trigger JOB_NAME+id does not exist in the scheduler (e.g. job was created but scheduling previously failed, or scheduler state was wiped while DB rows remain), or the new cron fails trigger-level validation that the earlier CronExpression.isValidExpression check passed.

Common situations: Database restored from backup while Quartz's RAMJobStore lost triggers — DB has the job but the scheduler does not, so rescheduleJob throws 'Trigger does not exist'; mixing persistent store and memory store between restarts.

Related errors


AI-assisted analysis of elunez/eladmin@55fbf70595 (2026-08-14). Data as JSON: /api/errors/54ac9018cb26ff90. Report an issue: GitHub.