



























@@ -294,4 +294,89 @@ describe("cron method validation", () => {
294294}),
295295);
296296});
297+298+it("returns INVALID_REQUEST when cron.add throws a croner parse error (#74066)", async () => {
299+const context = createCronContext();
300+context.cron.add.mockRejectedValueOnce(new TypeError("CronPattern: Expected 5 or 6 fields"));
301+const respond = vi.fn();
302+await cronHandlers["cron.add"]({
303+req: {} as never,
304+params: {
305+name: "bad-cron",
306+enabled: true,
307+schedule: { kind: "cron", cron: "not-a-cron-expr" },
308+sessionTarget: "isolated",
309+wakeMode: "next-heartbeat",
310+payload: { kind: "agentTurn", message: "ping" },
311+} as never,
312+respond: respond as never,
313+context: context as never,
314+client: null,
315+isWebchatConnect: () => false,
316+});
317+318+expect(respond).toHaveBeenCalledWith(
319+false,
320+undefined,
321+expect.objectContaining({
322+code: "INVALID_REQUEST",
323+message: expect.stringContaining("CronPattern"),
324+}),
325+);
326+});
327+328+it("returns INVALID_REQUEST when cron.update throws a croner parse error (#74066)", async () => {
329+const existingJob = createCronJob();
330+const context = createCronContext(existingJob);
331+context.cron.update.mockRejectedValueOnce(
332+new RangeError("CronPattern: Value out of range (99)"),
333+);
334+const respond = vi.fn();
335+await cronHandlers["cron.update"]({
336+req: {} as never,
337+params: {
338+id: existingJob.id,
339+patch: {
340+schedule: { kind: "cron", cron: "99 * * * *" },
341+},
342+} as never,
343+respond: respond as never,
344+context: context as never,
345+client: null,
346+isWebchatConnect: () => false,
347+});
348+349+expect(respond).toHaveBeenCalledWith(
350+false,
351+undefined,
352+expect.objectContaining({
353+code: "INVALID_REQUEST",
354+message: expect.stringContaining("CronPattern"),
355+}),
356+);
357+});
358+359+it("re-throws non-parse errors from cron.add instead of masking as INVALID_REQUEST", async () => {
360+const context = createCronContext();
361+context.cron.add.mockRejectedValueOnce(new Error("DB write failed"));
362+const respond = vi.fn();
363+await expect(
364+cronHandlers["cron.add"]({
365+req: {} as never,
366+params: {
367+name: "db-fail",
368+enabled: true,
369+schedule: { kind: "every", everyMs: 60_000 },
370+sessionTarget: "isolated",
371+wakeMode: "next-heartbeat",
372+payload: { kind: "agentTurn", message: "ping" },
373+} as never,
374+respond: respond as never,
375+context: context as never,
376+client: null,
377+isWebchatConnect: () => false,
378+}),
379+).rejects.toThrow("DB write failed");
380+expect(respond).not.toHaveBeenCalled();
381+});
297382});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。