|
| 1 | +import type { Backend } from "../core/backend.js"; |
1 | 2 | import { DEFAULT_RUN_IDEMPOTENCY_PERIOD_MS } from "../core/backend.js"; |
2 | 3 | import { |
3 | 4 | DEFAULT_WORKFLOW_RETRY_POLICY, |
4 | 5 | defineWorkflowSpec, |
5 | 6 | } from "../core/workflow-definition.js"; |
| 7 | +import type { WorkflowRun } from "../core/workflow-run.js"; |
6 | 8 | import { BackendPostgres } from "../postgres.js"; |
7 | 9 | import { |
8 | 10 | DEFAULT_POSTGRES_URL, |
@@ -242,6 +244,52 @@ describe("OpenWorkflow", () => { |
242 | 244 | expect(failedRun?.error).toEqual({ message: "boom" }); |
243 | 245 | }); |
244 | 246 |
|
| 247 | + test("result rejects when workflow run no longer exists", async () => { |
| 248 | + const workflowRun = createMockWorkflowRun({ |
| 249 | + workflowName: "missing-result-run", |
| 250 | + }); |
| 251 | + const backend = { |
| 252 | + createWorkflowRun: () => Promise.resolve(workflowRun), |
| 253 | + getWorkflowRun: () => Promise.resolve(null), |
| 254 | + } as unknown as Backend; |
| 255 | + const client = new OpenWorkflow({ backend }); |
| 256 | + |
| 257 | + const workflow = client.defineWorkflow( |
| 258 | + { name: "missing-result-run" }, |
| 259 | + noopFn, |
| 260 | + ); |
| 261 | + const handle = await workflow.run({ value: 1 }); |
| 262 | + |
| 263 | + await expect(handle.result()).rejects.toThrow( |
| 264 | + `Workflow run ${workflowRun.id} no longer exists`, |
| 265 | + ); |
| 266 | + }); |
| 267 | + |
| 268 | + test("result rejects when timeout is exceeded", async () => { |
| 269 | + const workflowRun = createMockWorkflowRun({ |
| 270 | + workflowName: "result-timeout-run", |
| 271 | + }); |
| 272 | + const backend = { |
| 273 | + createWorkflowRun: () => Promise.resolve(workflowRun), |
| 274 | + getWorkflowRun: () => |
| 275 | + Promise.resolve({ |
| 276 | + ...workflowRun, |
| 277 | + status: "pending" as const, |
| 278 | + }), |
| 279 | + } as unknown as Backend; |
| 280 | + const client = new OpenWorkflow({ backend }); |
| 281 | + |
| 282 | + const workflow = client.defineWorkflow( |
| 283 | + { name: "result-timeout-run" }, |
| 284 | + noopFn, |
| 285 | + ); |
| 286 | + const handle = await workflow.run({ value: 1 }); |
| 287 | + |
| 288 | + await expect(handle.result({ timeoutMs: -1 })).rejects.toThrow( |
| 289 | + `Timed out waiting for workflow run ${workflowRun.id} to finish`, |
| 290 | + ); |
| 291 | + }); |
| 292 | + |
245 | 293 | test("creates workflow run with deadline", async () => { |
246 | 294 | const backend = await createBackend(); |
247 | 295 | const client = new OpenWorkflow({ backend }); |
@@ -587,6 +635,36 @@ async function createBackend(): Promise<BackendPostgres> { |
587 | 635 | }); |
588 | 636 | } |
589 | 637 |
|
| 638 | +function createMockWorkflowRun( |
| 639 | + overrides: Partial<WorkflowRun> = {}, |
| 640 | +): WorkflowRun { |
| 641 | + const currentTime = new Date(); |
| 642 | + return { |
| 643 | + namespaceId: randomUUID(), |
| 644 | + id: randomUUID(), |
| 645 | + workflowName: "mock-workflow", |
| 646 | + version: null, |
| 647 | + status: "pending", |
| 648 | + idempotencyKey: null, |
| 649 | + config: {}, |
| 650 | + context: null, |
| 651 | + input: null, |
| 652 | + output: null, |
| 653 | + error: null, |
| 654 | + attempts: 0, |
| 655 | + parentStepAttemptNamespaceId: null, |
| 656 | + parentStepAttemptId: null, |
| 657 | + workerId: null, |
| 658 | + availableAt: currentTime, |
| 659 | + deadlineAt: null, |
| 660 | + startedAt: null, |
| 661 | + finishedAt: null, |
| 662 | + createdAt: currentTime, |
| 663 | + updatedAt: currentTime, |
| 664 | + ...overrides, |
| 665 | + }; |
| 666 | +} |
| 667 | + |
590 | 668 | function sleep(ms: number): Promise<void> { |
591 | 669 | return new Promise((resolve) => setTimeout(resolve, ms)); |
592 | 670 | } |
|
0 commit comments