From 50d6f3fb23499eb0b014a23821ef51fb2581ded6 Mon Sep 17 00:00:00 2001 From: Martha Ramirez <59023744+YNight-FZQ@users.noreply.github.com> Date: Sat, 27 Jun 2026 14:03:52 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BF=87=E6=BB=A4=20delCron=20=E4=B8=AD=20sche?= =?UTF-8?q?duleStacks=20=E7=9A=84=20null=20job?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit nodeSchedule.scheduleJob() 对无效 cron 表达式(如 "0 * /6 * * *", 空格分开了 * /6)会返回 null,原代码原样存入 scheduleStacks 数组。 delCron 取消时对 null 调 cancel() 抛出 UNKNOWN 错误,导致 gRPC handler 中断、HTTP 端 cronService.remove() 跳过 setCrontab(), crontab.list 残留已删任务的记录,导致订阅更新时 gen_list_repo() 误判脚本已存在、不再重新注册。 过滤 null 并对每个 cancel 调用加 try/catch 容错。 --- back/schedule/delCron.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/back/schedule/delCron.ts b/back/schedule/delCron.ts index 6e35c080..f711deea 100644 --- a/back/schedule/delCron.ts +++ b/back/schedule/delCron.ts @@ -13,7 +13,20 @@ const delCron = ( '[schedule][取消定时任务] 任务ID: %s', id, ); - scheduleStacks.get(id)?.forEach(x => x.cancel()); + // 过滤掉 nodeSchedule.scheduleJob() 对无效表达式返回的 null, + // 否则对 null 调 cancel() 会让整个取消流程抛出 UNKNOWN 错误, + // 进而导致 HTTP 端的 remove() 跳过 setCrontab(),造成 crontab.list 残留。 + scheduleStacks.get(id)?.filter((x) => x != null).forEach((x) => { + try { + x.cancel(); + } catch (error: any) { + Logger.warn( + '[schedule][取消任务失败] 任务ID: %s, 错误: %s', + id, + error?.message || error, + ); + } + }); scheduleStacks.delete(id); } }