Skip to content

Commit a799b92

Browse files
committed
test on failure
1 parent af331a1 commit a799b92

File tree

1 file changed

+195
-0
lines changed

1 file changed

+195
-0
lines changed

packages/core/test/taskExecutor.test.ts

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,4 +524,199 @@ describe("TaskExecutor", () => {
524524
},
525525
});
526526
});
527+
528+
test("should call onFailure hooks with error when task fails", async () => {
529+
const globalFailureOrder: string[] = [];
530+
const failurePayloads: any[] = [];
531+
const failureErrors: any[] = [];
532+
const failureInits: any[] = [];
533+
534+
// Register global init hook to provide init data
535+
lifecycleHooks.registerGlobalInitHook({
536+
id: "test-init",
537+
fn: async () => {
538+
return {
539+
foo: "bar",
540+
};
541+
},
542+
});
543+
544+
// Register two global failure hooks
545+
lifecycleHooks.registerGlobalFailureHook({
546+
id: "global-failure-1",
547+
fn: async ({ payload, error, init }) => {
548+
console.log("Executing global failure hook 1");
549+
globalFailureOrder.push("global-1");
550+
failurePayloads.push(payload);
551+
failureErrors.push(error);
552+
failureInits.push(init);
553+
},
554+
});
555+
556+
lifecycleHooks.registerGlobalFailureHook({
557+
id: "global-failure-2",
558+
fn: async ({ payload, error, init }) => {
559+
console.log("Executing global failure hook 2");
560+
globalFailureOrder.push("global-2");
561+
failurePayloads.push(payload);
562+
failureErrors.push(error);
563+
failureInits.push(init);
564+
},
565+
});
566+
567+
// Register task-specific failure hook
568+
lifecycleHooks.registerTaskFailureHook("test-task", {
569+
id: "task-failure",
570+
fn: async ({ payload, error, init }) => {
571+
console.log("Executing task failure hook");
572+
globalFailureOrder.push("task");
573+
failurePayloads.push(payload);
574+
failureErrors.push(error);
575+
failureInits.push(init);
576+
},
577+
});
578+
579+
// Verify hooks are registered
580+
const globalHooks = lifecycleHooks.getGlobalFailureHooks();
581+
console.log(
582+
"Registered global hooks:",
583+
globalHooks.map((h) => h.id)
584+
);
585+
const taskHook = lifecycleHooks.getTaskFailureHook("test-task");
586+
console.log("Registered task hook:", taskHook ? "yes" : "no");
587+
588+
const expectedError = new Error("Task failed intentionally");
589+
590+
const task = {
591+
id: "test-task",
592+
fns: {
593+
run: async (payload: any, params: RunFnParams<any>) => {
594+
throw expectedError;
595+
},
596+
},
597+
};
598+
599+
const tracingSDK = new TracingSDK({
600+
url: "http://localhost:4318",
601+
});
602+
603+
const tracer = new TriggerTracer({
604+
name: "test-task",
605+
version: "1.0.0",
606+
tracer: tracingSDK.getTracer("test-task"),
607+
logger: tracingSDK.getLogger("test-task"),
608+
});
609+
610+
const consoleInterceptor = new ConsoleInterceptor(tracingSDK.getLogger("test-task"), false);
611+
612+
const executor = new TaskExecutor(task, {
613+
tracingSDK,
614+
tracer,
615+
consoleInterceptor,
616+
retries: {
617+
enabledInDev: false,
618+
default: {
619+
maxAttempts: 1,
620+
},
621+
},
622+
handleErrorFn: undefined,
623+
});
624+
625+
const execution: TaskRunExecution = {
626+
task: {
627+
id: "test-task",
628+
filePath: "test-task.ts",
629+
},
630+
attempt: {
631+
number: 1,
632+
startedAt: new Date(),
633+
id: "test-attempt-id",
634+
status: "success",
635+
backgroundWorkerId: "test-background-worker-id",
636+
backgroundWorkerTaskId: "test-background-worker-task-id",
637+
},
638+
run: {
639+
id: "test-run-id",
640+
payload: '{"test":"data"}',
641+
payloadType: "application/json",
642+
metadata: {},
643+
startedAt: new Date(),
644+
tags: [],
645+
isTest: false,
646+
createdAt: new Date(),
647+
durationMs: 0,
648+
costInCents: 0,
649+
baseCostInCents: 0,
650+
priority: 0,
651+
},
652+
machine: {
653+
name: "micro",
654+
cpu: 1,
655+
memory: 1,
656+
centsPerMs: 0,
657+
},
658+
queue: {
659+
name: "test-queue",
660+
id: "test-queue-id",
661+
},
662+
environment: {
663+
type: "PRODUCTION",
664+
id: "test-environment-id",
665+
slug: "test-environment-slug",
666+
},
667+
organization: {
668+
id: "test-organization-id",
669+
name: "test-organization-name",
670+
slug: "test-organization-slug",
671+
},
672+
project: {
673+
id: "test-project-id",
674+
name: "test-project-name",
675+
slug: "test-project-slug",
676+
ref: "test-project-ref",
677+
},
678+
};
679+
680+
const worker: ServerBackgroundWorker = {
681+
id: "test-background-worker-id",
682+
version: "1.0.0",
683+
contentHash: "test-content-hash",
684+
engine: "V2",
685+
};
686+
687+
const result = await executor.execute(execution, worker, {});
688+
689+
// Verify hooks were called in correct order
690+
expect(globalFailureOrder).toEqual(["global-1", "global-2", "task"]);
691+
692+
// Verify each hook received the correct payload
693+
failurePayloads.forEach((payload) => {
694+
expect(payload).toEqual({ test: "data" });
695+
});
696+
697+
// Verify each hook received the correct error
698+
failureErrors.forEach((error) => {
699+
expect(error).toBe(expectedError);
700+
});
701+
702+
// Verify each hook received the correct init data
703+
failureInits.forEach((init) => {
704+
expect(init).toEqual({ foo: "bar" });
705+
});
706+
707+
// Verify the final result contains the error
708+
expect(result).toEqual({
709+
result: {
710+
ok: false,
711+
id: "test-run-id",
712+
error: {
713+
type: "BUILT_IN_ERROR",
714+
message: "Task failed intentionally",
715+
name: "Error",
716+
stackTrace: expect.any(String),
717+
},
718+
skippedRetrying: false,
719+
},
720+
});
721+
});
527722
});

0 commit comments

Comments
 (0)