@workflow/world-testing 4.1.0-beta.70 → 4.1.0-beta.71
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -49437,6 +49437,19 @@ async function deleteJSON(filePath) {
|
|
|
49437
49437
|
}
|
|
49438
49438
|
}
|
|
49439
49439
|
__name(deleteJSON, "deleteJSON");
|
|
49440
|
+
async function writeExclusive(filePath, data) {
|
|
49441
|
+
await ensureDir(import_node_path2.default.dirname(filePath));
|
|
49442
|
+
try {
|
|
49443
|
+
await import_node_fs.promises.writeFile(filePath, data, { flag: "wx" });
|
|
49444
|
+
return true;
|
|
49445
|
+
} catch (error48) {
|
|
49446
|
+
if (error48.code === "EEXIST") {
|
|
49447
|
+
return false;
|
|
49448
|
+
}
|
|
49449
|
+
throw error48;
|
|
49450
|
+
}
|
|
49451
|
+
}
|
|
49452
|
+
__name(writeExclusive, "writeExclusive");
|
|
49440
49453
|
async function listJSONFiles(dirPath) {
|
|
49441
49454
|
return listFilesByExtension(dirPath, ".json");
|
|
49442
49455
|
}
|
|
@@ -49590,6 +49603,11 @@ function filterHookData(hook, resolveData) {
|
|
|
49590
49603
|
__name(filterHookData, "filterHookData");
|
|
49591
49604
|
|
|
49592
49605
|
// ../world-local/dist/storage/helpers.js
|
|
49606
|
+
var import_node_crypto2 = require("node:crypto");
|
|
49607
|
+
function hashToken(token) {
|
|
49608
|
+
return (0, import_node_crypto2.createHash)("sha256").update(token).digest("hex");
|
|
49609
|
+
}
|
|
49610
|
+
__name(hashToken, "hashToken");
|
|
49593
49611
|
var monotonicUlid = monotonicFactory(() => Math.random());
|
|
49594
49612
|
var getObjectCreatedAt = /* @__PURE__ */ __name((idPrefix) => (filename) => {
|
|
49595
49613
|
const replaceRegex = new RegExp(`^${idPrefix}_`, "g");
|
|
@@ -49678,6 +49696,8 @@ async function deleteAllHooksForRun(basedir, runId) {
|
|
|
49678
49696
|
const hookPath = import_node_path3.default.join(hooksDir, `${file2}.json`);
|
|
49679
49697
|
const hook = await readJSON(hookPath, HookSchema);
|
|
49680
49698
|
if (hook && hook.runId === runId) {
|
|
49699
|
+
const constraintPath = import_node_path3.default.join(hooksDir, "tokens", `${hashToken(hook.token)}.json`);
|
|
49700
|
+
await deleteJSON(constraintPath);
|
|
49681
49701
|
await deleteJSON(hookPath);
|
|
49682
49702
|
}
|
|
49683
49703
|
}
|
|
@@ -50086,18 +50106,13 @@ function createEventsStorage(basedir) {
|
|
|
50086
50106
|
data.eventType === "hook_created" && "eventData" in data
|
|
50087
50107
|
) {
|
|
50088
50108
|
const hookData = data.eventData;
|
|
50089
|
-
const
|
|
50090
|
-
const
|
|
50091
|
-
|
|
50092
|
-
|
|
50093
|
-
|
|
50094
|
-
|
|
50095
|
-
|
|
50096
|
-
hasConflict = true;
|
|
50097
|
-
break;
|
|
50098
|
-
}
|
|
50099
|
-
}
|
|
50100
|
-
if (hasConflict) {
|
|
50109
|
+
const constraintPath = import_node_path5.default.join(basedir, "hooks", "tokens", `${hashToken(hookData.token)}.json`);
|
|
50110
|
+
const tokenClaimed = await writeExclusive(constraintPath, JSON.stringify({
|
|
50111
|
+
token: hookData.token,
|
|
50112
|
+
hookId: data.correlationId,
|
|
50113
|
+
runId: effectiveRunId
|
|
50114
|
+
}));
|
|
50115
|
+
if (!tokenClaimed) {
|
|
50101
50116
|
const conflictEvent = {
|
|
50102
50117
|
eventType: "hook_conflict",
|
|
50103
50118
|
correlationId: data.correlationId,
|
|
@@ -50138,6 +50153,11 @@ function createEventsStorage(basedir) {
|
|
|
50138
50153
|
await writeJSON(hookPath, hook);
|
|
50139
50154
|
} else if (data.eventType === "hook_disposed") {
|
|
50140
50155
|
const hookPath = import_node_path5.default.join(basedir, "hooks", `${data.correlationId}.json`);
|
|
50156
|
+
const existingHook = await readJSON(hookPath, HookSchema);
|
|
50157
|
+
if (existingHook) {
|
|
50158
|
+
const disposedConstraintPath = import_node_path5.default.join(basedir, "hooks", "tokens", `${hashToken(existingHook.token)}.json`);
|
|
50159
|
+
await deleteJSON(disposedConstraintPath);
|
|
50160
|
+
}
|
|
50141
50161
|
await deleteJSON(hookPath);
|
|
50142
50162
|
} else if (data.eventType === "wait_created" && "eventData" in data) {
|
|
50143
50163
|
const waitData = data.eventData;
|
|
@@ -50602,7 +50622,7 @@ function createLocalWorld(args) {
|
|
|
50602
50622
|
__name(createLocalWorld, "createLocalWorld");
|
|
50603
50623
|
|
|
50604
50624
|
// ../world-vercel/dist/encryption.js
|
|
50605
|
-
var
|
|
50625
|
+
var import_node_crypto3 = require("node:crypto");
|
|
50606
50626
|
var import_oidc2 = __toESM(require_dist2(), 1);
|
|
50607
50627
|
|
|
50608
50628
|
// ../world-vercel/dist/http-client.js
|
|
@@ -50636,9 +50656,9 @@ async function deriveRunKey(deploymentKey, projectId, runId) {
|
|
|
50636
50656
|
if (!projectId || typeof projectId !== "string") {
|
|
50637
50657
|
throw new Error("projectId must be a non-empty string");
|
|
50638
50658
|
}
|
|
50639
|
-
const baseKey = await
|
|
50659
|
+
const baseKey = await import_node_crypto3.webcrypto.subtle.importKey("raw", deploymentKey, "HKDF", false, ["deriveBits"]);
|
|
50640
50660
|
const info = new TextEncoder().encode(`${projectId}|${runId}`);
|
|
50641
|
-
const derivedBits = await
|
|
50661
|
+
const derivedBits = await import_node_crypto3.webcrypto.subtle.deriveBits(
|
|
50642
50662
|
{
|
|
50643
50663
|
name: "HKDF",
|
|
50644
50664
|
hash: "SHA-256",
|
|
@@ -54381,7 +54401,7 @@ var createWorld = /* @__PURE__ */ __name(() => {
|
|
|
54381
54401
|
"WORKFLOW_VERCEL_AUTH_TOKEN",
|
|
54382
54402
|
"WORKFLOW_VERCEL_ENV"
|
|
54383
54403
|
].filter((key) => process.env[key]);
|
|
54384
|
-
if (staleEnvVars.length > 0) {
|
|
54404
|
+
if (staleEnvVars.length > 0 && process.env.VERCEL === "1") {
|
|
54385
54405
|
console.warn(`[workflow] Warning: ${staleEnvVars.join(", ")} env var(s) are set but have no effect at runtime. These are only used by the Workflow CLI. Remove them from your Vercel project environment variables.`);
|
|
54386
54406
|
}
|
|
54387
54407
|
return createVercelWorld();
|
|
@@ -54552,69 +54572,6 @@ function getQueueOverhead(message) {
|
|
|
54552
54572
|
}
|
|
54553
54573
|
}
|
|
54554
54574
|
__name(getQueueOverhead, "getQueueOverhead");
|
|
54555
|
-
async function withThrottleRetry(fn) {
|
|
54556
|
-
try {
|
|
54557
|
-
return await fn();
|
|
54558
|
-
} catch (err) {
|
|
54559
|
-
if (WorkflowAPIError.is(err) && err.status === 429) {
|
|
54560
|
-
const retryAfterSeconds = Math.max(
|
|
54561
|
-
// If we don't have a retry-after value, 30s seems a reasonable default
|
|
54562
|
-
// to avoid re-trying during the unknown rate-limiting period.
|
|
54563
|
-
1,
|
|
54564
|
-
typeof err.retryAfter === "number" ? err.retryAfter : 30
|
|
54565
|
-
);
|
|
54566
|
-
if (retryAfterSeconds < 10) {
|
|
54567
|
-
runtimeLogger.warn("Throttled by workflow-server (429), retrying in-process", {
|
|
54568
|
-
retryAfterSeconds,
|
|
54569
|
-
url: err.url
|
|
54570
|
-
});
|
|
54571
|
-
await new Promise((resolve3) => setTimeout(resolve3, retryAfterSeconds * 1e3));
|
|
54572
|
-
try {
|
|
54573
|
-
return await fn();
|
|
54574
|
-
} catch (retryErr) {
|
|
54575
|
-
if (WorkflowAPIError.is(retryErr) && retryErr.status === 429) {
|
|
54576
|
-
const retryRetryAfter = Math.max(1, typeof retryErr.retryAfter === "number" ? retryErr.retryAfter : 1);
|
|
54577
|
-
runtimeLogger.warn("Throttled again on retry, deferring to queue", {
|
|
54578
|
-
retryAfterSeconds: retryRetryAfter
|
|
54579
|
-
});
|
|
54580
|
-
return { timeoutSeconds: retryRetryAfter };
|
|
54581
|
-
}
|
|
54582
|
-
throw retryErr;
|
|
54583
|
-
}
|
|
54584
|
-
}
|
|
54585
|
-
runtimeLogger.warn("Throttled by workflow-server (429), deferring to queue", {
|
|
54586
|
-
retryAfterSeconds,
|
|
54587
|
-
url: err.url
|
|
54588
|
-
});
|
|
54589
|
-
return { timeoutSeconds: retryAfterSeconds };
|
|
54590
|
-
}
|
|
54591
|
-
throw err;
|
|
54592
|
-
}
|
|
54593
|
-
}
|
|
54594
|
-
__name(withThrottleRetry, "withThrottleRetry");
|
|
54595
|
-
async function withServerErrorRetry(fn) {
|
|
54596
|
-
const delays = [500, 1e3, 2e3];
|
|
54597
|
-
for (let attempt = 0; attempt <= delays.length; attempt++) {
|
|
54598
|
-
try {
|
|
54599
|
-
return await fn();
|
|
54600
|
-
} catch (err) {
|
|
54601
|
-
if (WorkflowAPIError.is(err) && err.status !== void 0 && err.status >= 500 && attempt < delays.length) {
|
|
54602
|
-
runtimeLogger.warn("Server error (5xx) from workflow-server, retrying in-process", {
|
|
54603
|
-
status: err.status,
|
|
54604
|
-
attempt: attempt + 1,
|
|
54605
|
-
maxRetries: delays.length,
|
|
54606
|
-
nextDelayMs: delays[attempt],
|
|
54607
|
-
url: err.url
|
|
54608
|
-
});
|
|
54609
|
-
await new Promise((resolve3) => setTimeout(resolve3, delays[attempt]));
|
|
54610
|
-
continue;
|
|
54611
|
-
}
|
|
54612
|
-
throw err;
|
|
54613
|
-
}
|
|
54614
|
-
}
|
|
54615
|
-
throw new Error("withServerErrorRetry: unreachable");
|
|
54616
|
-
}
|
|
54617
|
-
__name(withServerErrorRetry, "withServerErrorRetry");
|
|
54618
54575
|
|
|
54619
54576
|
// ../core/dist/runtime/suspension-handler.js
|
|
54620
54577
|
var import_functions = __toESM(require_functions(), 1);
|
|
@@ -58257,18 +58214,18 @@ var stepHandler = getWorldHandlers().createQueueHandler("__wkf_step_", async (me
|
|
|
58257
58214
|
});
|
|
58258
58215
|
let step;
|
|
58259
58216
|
try {
|
|
58260
|
-
const startResult = await
|
|
58217
|
+
const startResult = await world.events.create(workflowRunId, {
|
|
58261
58218
|
eventType: "step_started",
|
|
58262
58219
|
specVersion: SPEC_VERSION_CURRENT,
|
|
58263
58220
|
correlationId: stepId
|
|
58264
|
-
})
|
|
58221
|
+
});
|
|
58265
58222
|
if (!startResult.step) {
|
|
58266
58223
|
throw new WorkflowRuntimeError(`step_started event for "${stepId}" did not return step entity`);
|
|
58267
58224
|
}
|
|
58268
58225
|
step = startResult.step;
|
|
58269
58226
|
} catch (err) {
|
|
58270
58227
|
if (WorkflowAPIError.is(err)) {
|
|
58271
|
-
if (
|
|
58228
|
+
if (err.status === 429) {
|
|
58272
58229
|
const retryRetryAfter = Math.max(1, typeof err.retryAfter === "number" ? err.retryAfter : 1);
|
|
58273
58230
|
runtimeLogger.warn("Throttled again on retry, deferring to queue", {
|
|
58274
58231
|
retryAfterSeconds: retryRetryAfter
|
|
@@ -58377,28 +58334,57 @@ var stepHandler = getWorldHandlers().createQueueHandler("__wkf_step_", async (me
|
|
|
58377
58334
|
});
|
|
58378
58335
|
return;
|
|
58379
58336
|
}
|
|
58380
|
-
|
|
58381
|
-
|
|
58382
|
-
|
|
58383
|
-
|
|
58384
|
-
|
|
58385
|
-
|
|
58386
|
-
|
|
58387
|
-
|
|
58388
|
-
|
|
58389
|
-
|
|
58390
|
-
|
|
58391
|
-
|
|
58392
|
-
|
|
58393
|
-
|
|
58394
|
-
|
|
58395
|
-
|
|
58337
|
+
const attempt = step.attempt;
|
|
58338
|
+
if (!step.startedAt) {
|
|
58339
|
+
const errorMessage = `Step "${stepId}" has no "startedAt" timestamp`;
|
|
58340
|
+
runtimeLogger.error("Fatal runtime error during step setup", {
|
|
58341
|
+
workflowRunId,
|
|
58342
|
+
stepId,
|
|
58343
|
+
error: errorMessage
|
|
58344
|
+
});
|
|
58345
|
+
try {
|
|
58346
|
+
await world.events.create(workflowRunId, {
|
|
58347
|
+
eventType: "step_failed",
|
|
58348
|
+
specVersion: SPEC_VERSION_CURRENT,
|
|
58349
|
+
correlationId: stepId,
|
|
58350
|
+
eventData: {
|
|
58351
|
+
error: errorMessage,
|
|
58352
|
+
stack: new Error(errorMessage).stack ?? ""
|
|
58353
|
+
}
|
|
58396
58354
|
});
|
|
58397
|
-
|
|
58355
|
+
} catch (failErr) {
|
|
58356
|
+
if (WorkflowAPIError.is(failErr) && failErr.status === 409) {
|
|
58357
|
+
return;
|
|
58358
|
+
}
|
|
58359
|
+
throw failErr;
|
|
58360
|
+
}
|
|
58361
|
+
await queueMessage(world, getWorkflowQueueName(workflowName), {
|
|
58362
|
+
runId: workflowRunId,
|
|
58363
|
+
traceCarrier: await serializeTraceCarrier(),
|
|
58364
|
+
requestedAt: /* @__PURE__ */ new Date()
|
|
58365
|
+
});
|
|
58366
|
+
return;
|
|
58367
|
+
}
|
|
58368
|
+
const stepStartedAt = step.startedAt;
|
|
58369
|
+
const ops = [];
|
|
58370
|
+
const rawKey = await world.getEncryptionKeyForRun?.(workflowRunId);
|
|
58371
|
+
const encryptionKey = rawKey ? await importKey(rawKey) : void 0;
|
|
58372
|
+
const hydratedInput = await trace2("step.hydrate", {}, async (hydrateSpan) => {
|
|
58373
|
+
const startTime = Date.now();
|
|
58374
|
+
const result2 = await hydrateStepArguments(step.input, workflowRunId, encryptionKey, ops);
|
|
58375
|
+
const durationMs = Date.now() - startTime;
|
|
58376
|
+
hydrateSpan?.setAttributes({
|
|
58377
|
+
...StepArgumentsCount(result2.args.length),
|
|
58378
|
+
...QueueDeserializeTimeMs(durationMs)
|
|
58398
58379
|
});
|
|
58399
|
-
|
|
58400
|
-
|
|
58401
|
-
|
|
58380
|
+
return result2;
|
|
58381
|
+
});
|
|
58382
|
+
const args = hydratedInput.args;
|
|
58383
|
+
const thisVal = hydratedInput.thisVal ?? null;
|
|
58384
|
+
let userCodeError;
|
|
58385
|
+
let userCodeFailed = false;
|
|
58386
|
+
const executionStartTime = Date.now();
|
|
58387
|
+
try {
|
|
58402
58388
|
result = await trace2("step.execute", {}, async () => {
|
|
58403
58389
|
return await contextStorage.run({
|
|
58404
58390
|
stepMetadata: {
|
|
@@ -58420,63 +58406,29 @@ var stepHandler = getWorldHandlers().createQueueHandler("__wkf_step_", async (me
|
|
|
58420
58406
|
encryptionKey
|
|
58421
58407
|
}, () => stepFn.apply(thisVal, args));
|
|
58422
58408
|
});
|
|
58423
|
-
|
|
58424
|
-
|
|
58425
|
-
|
|
58426
|
-
|
|
58427
|
-
|
|
58428
|
-
|
|
58429
|
-
|
|
58430
|
-
|
|
58431
|
-
|
|
58432
|
-
|
|
58433
|
-
|
|
58434
|
-
|
|
58435
|
-
|
|
58436
|
-
|
|
58437
|
-
|
|
58438
|
-
|
|
58439
|
-
|
|
58440
|
-
|
|
58441
|
-
|
|
58442
|
-
|
|
58443
|
-
const [, traceCarrier] = await Promise.all([
|
|
58444
|
-
withServerErrorRetry(() => world.events.create(workflowRunId, {
|
|
58445
|
-
eventType: "step_completed",
|
|
58446
|
-
specVersion: SPEC_VERSION_CURRENT,
|
|
58447
|
-
correlationId: stepId,
|
|
58448
|
-
eventData: {
|
|
58449
|
-
result
|
|
58450
|
-
}
|
|
58451
|
-
})).catch((err) => {
|
|
58452
|
-
if (WorkflowAPIError.is(err) && err.status === 409) {
|
|
58453
|
-
runtimeLogger.warn("Tried completing step, but step has already finished.", {
|
|
58454
|
-
workflowRunId,
|
|
58455
|
-
stepId,
|
|
58456
|
-
stepName,
|
|
58457
|
-
message: err.message
|
|
58458
|
-
});
|
|
58459
|
-
stepCompleted409 = true;
|
|
58460
|
-
return;
|
|
58461
|
-
}
|
|
58409
|
+
} catch (err) {
|
|
58410
|
+
userCodeError = err;
|
|
58411
|
+
userCodeFailed = true;
|
|
58412
|
+
}
|
|
58413
|
+
const executionTimeMs = Date.now() - executionStartTime;
|
|
58414
|
+
span?.setAttributes({
|
|
58415
|
+
...QueueExecutionTimeMs(executionTimeMs)
|
|
58416
|
+
});
|
|
58417
|
+
if (userCodeFailed) {
|
|
58418
|
+
const err = userCodeError;
|
|
58419
|
+
if (WorkflowAPIError.is(err)) {
|
|
58420
|
+
if (err.status === 410) {
|
|
58421
|
+
stepLogger.info("Workflow run already completed, skipping step", {
|
|
58422
|
+
workflowRunId,
|
|
58423
|
+
stepId,
|
|
58424
|
+
message: err.message
|
|
58425
|
+
});
|
|
58426
|
+
return;
|
|
58427
|
+
}
|
|
58428
|
+
if (err.status !== void 0 && err.status >= 500) {
|
|
58462
58429
|
throw err;
|
|
58463
|
-
}
|
|
58464
|
-
serializeTraceCarrier()
|
|
58465
|
-
]);
|
|
58466
|
-
if (stepCompleted409) {
|
|
58467
|
-
return;
|
|
58430
|
+
}
|
|
58468
58431
|
}
|
|
58469
|
-
span?.setAttributes({
|
|
58470
|
-
...StepStatus("completed"),
|
|
58471
|
-
...StepResultType(typeof result)
|
|
58472
|
-
});
|
|
58473
|
-
await queueMessage(world, getWorkflowQueueName(workflowName), {
|
|
58474
|
-
runId: workflowRunId,
|
|
58475
|
-
traceCarrier,
|
|
58476
|
-
requestedAt: /* @__PURE__ */ new Date()
|
|
58477
|
-
});
|
|
58478
|
-
return;
|
|
58479
|
-
} catch (err) {
|
|
58480
58432
|
const normalizedError = await normalizeUnknownError(err);
|
|
58481
58433
|
const normalizedStack = normalizedError.stack || getErrorStack(err) || "";
|
|
58482
58434
|
if (err instanceof Error) {
|
|
@@ -58492,26 +58444,6 @@ var stepHandler = getWorldHandlers().createQueueHandler("__wkf_step_", async (me
|
|
|
58492
58444
|
...ErrorCategory(errorCategory),
|
|
58493
58445
|
...ErrorRetryable(!isFatal)
|
|
58494
58446
|
});
|
|
58495
|
-
if (WorkflowAPIError.is(err)) {
|
|
58496
|
-
if (err.status === 410) {
|
|
58497
|
-
stepLogger.info("Workflow run already completed, skipping step", {
|
|
58498
|
-
workflowRunId,
|
|
58499
|
-
stepId,
|
|
58500
|
-
message: err.message
|
|
58501
|
-
});
|
|
58502
|
-
return;
|
|
58503
|
-
}
|
|
58504
|
-
if (err.status !== void 0 && err.status >= 500) {
|
|
58505
|
-
runtimeLogger.warn("Persistent server error (5xx) during step, deferring to queue retry", {
|
|
58506
|
-
status: err.status,
|
|
58507
|
-
workflowRunId,
|
|
58508
|
-
stepId,
|
|
58509
|
-
error: err.message,
|
|
58510
|
-
url: err.url
|
|
58511
|
-
});
|
|
58512
|
-
throw err;
|
|
58513
|
-
}
|
|
58514
|
-
}
|
|
58515
58447
|
if (isFatal) {
|
|
58516
58448
|
stepLogger.error("Encountered FatalError while executing step, bubbling up to parent workflow", {
|
|
58517
58449
|
workflowRunId,
|
|
@@ -58519,7 +58451,7 @@ var stepHandler = getWorldHandlers().createQueueHandler("__wkf_step_", async (me
|
|
|
58519
58451
|
errorStack: normalizedStack
|
|
58520
58452
|
});
|
|
58521
58453
|
try {
|
|
58522
|
-
await
|
|
58454
|
+
await world.events.create(workflowRunId, {
|
|
58523
58455
|
eventType: "step_failed",
|
|
58524
58456
|
specVersion: SPEC_VERSION_CURRENT,
|
|
58525
58457
|
correlationId: stepId,
|
|
@@ -58527,7 +58459,7 @@ var stepHandler = getWorldHandlers().createQueueHandler("__wkf_step_", async (me
|
|
|
58527
58459
|
error: normalizedError.message,
|
|
58528
58460
|
stack: normalizedStack
|
|
58529
58461
|
}
|
|
58530
|
-
})
|
|
58462
|
+
});
|
|
58531
58463
|
} catch (stepFailErr) {
|
|
58532
58464
|
if (WorkflowAPIError.is(stepFailErr) && stepFailErr.status === 409) {
|
|
58533
58465
|
runtimeLogger.warn("Tried failing step, but step has already finished.", {
|
|
@@ -58562,7 +58494,7 @@ var stepHandler = getWorldHandlers().createQueueHandler("__wkf_step_", async (me
|
|
|
58562
58494
|
});
|
|
58563
58495
|
const errorMessage = `Step "${stepName}" failed after ${maxRetries2} ${pluralize("retry", "retries", maxRetries2)}: ${normalizedError.message}`;
|
|
58564
58496
|
try {
|
|
58565
|
-
await
|
|
58497
|
+
await world.events.create(workflowRunId, {
|
|
58566
58498
|
eventType: "step_failed",
|
|
58567
58499
|
specVersion: SPEC_VERSION_CURRENT,
|
|
58568
58500
|
correlationId: stepId,
|
|
@@ -58570,7 +58502,7 @@ var stepHandler = getWorldHandlers().createQueueHandler("__wkf_step_", async (me
|
|
|
58570
58502
|
error: errorMessage,
|
|
58571
58503
|
stack: normalizedStack
|
|
58572
58504
|
}
|
|
58573
|
-
})
|
|
58505
|
+
});
|
|
58574
58506
|
} catch (stepFailErr) {
|
|
58575
58507
|
if (WorkflowAPIError.is(stepFailErr) && stepFailErr.status === 409) {
|
|
58576
58508
|
runtimeLogger.warn("Tried failing step, but step has already finished.", {
|
|
@@ -58604,7 +58536,7 @@ var stepHandler = getWorldHandlers().createQueueHandler("__wkf_step_", async (me
|
|
|
58604
58536
|
});
|
|
58605
58537
|
}
|
|
58606
58538
|
try {
|
|
58607
|
-
await
|
|
58539
|
+
await world.events.create(workflowRunId, {
|
|
58608
58540
|
eventType: "step_retrying",
|
|
58609
58541
|
specVersion: SPEC_VERSION_CURRENT,
|
|
58610
58542
|
correlationId: stepId,
|
|
@@ -58615,7 +58547,7 @@ var stepHandler = getWorldHandlers().createQueueHandler("__wkf_step_", async (me
|
|
|
58615
58547
|
retryAfter: err.retryAfter
|
|
58616
58548
|
}
|
|
58617
58549
|
}
|
|
58618
|
-
})
|
|
58550
|
+
});
|
|
58619
58551
|
} catch (stepRetryErr) {
|
|
58620
58552
|
if (WorkflowAPIError.is(stepRetryErr) && stepRetryErr.status === 409) {
|
|
58621
58553
|
runtimeLogger.warn("Tried retrying step, but step has already finished.", {
|
|
@@ -58641,10 +58573,62 @@ var stepHandler = getWorldHandlers().createQueueHandler("__wkf_step_", async (me
|
|
|
58641
58573
|
return { timeoutSeconds };
|
|
58642
58574
|
}
|
|
58643
58575
|
}
|
|
58576
|
+
await queueMessage(world, getWorkflowQueueName(workflowName), {
|
|
58577
|
+
runId: workflowRunId,
|
|
58578
|
+
traceCarrier: await serializeTraceCarrier(),
|
|
58579
|
+
requestedAt: /* @__PURE__ */ new Date()
|
|
58580
|
+
});
|
|
58581
|
+
return;
|
|
58582
|
+
}
|
|
58583
|
+
result = await trace2("step.dehydrate", {}, async (dehydrateSpan) => {
|
|
58584
|
+
const startTime = Date.now();
|
|
58585
|
+
const dehydrated = await dehydrateStepReturnValue(result, workflowRunId, encryptionKey, ops);
|
|
58586
|
+
const durationMs = Date.now() - startTime;
|
|
58587
|
+
dehydrateSpan?.setAttributes({
|
|
58588
|
+
...QueueSerializeTimeMs(durationMs),
|
|
58589
|
+
...StepResultType(typeof dehydrated)
|
|
58590
|
+
});
|
|
58591
|
+
return dehydrated;
|
|
58592
|
+
});
|
|
58593
|
+
(0, import_functions5.waitUntil)(Promise.all(ops).catch((err) => {
|
|
58594
|
+
const isAbortError = err?.name === "AbortError" || err?.name === "ResponseAborted";
|
|
58595
|
+
if (!isAbortError)
|
|
58596
|
+
throw err;
|
|
58597
|
+
}));
|
|
58598
|
+
let stepCompleted409 = false;
|
|
58599
|
+
const [, traceCarrier] = await Promise.all([
|
|
58600
|
+
world.events.create(workflowRunId, {
|
|
58601
|
+
eventType: "step_completed",
|
|
58602
|
+
specVersion: SPEC_VERSION_CURRENT,
|
|
58603
|
+
correlationId: stepId,
|
|
58604
|
+
eventData: {
|
|
58605
|
+
result
|
|
58606
|
+
}
|
|
58607
|
+
}).catch((err) => {
|
|
58608
|
+
if (WorkflowAPIError.is(err) && err.status === 409) {
|
|
58609
|
+
runtimeLogger.warn("Tried completing step, but step has already finished.", {
|
|
58610
|
+
workflowRunId,
|
|
58611
|
+
stepId,
|
|
58612
|
+
stepName,
|
|
58613
|
+
message: err.message
|
|
58614
|
+
});
|
|
58615
|
+
stepCompleted409 = true;
|
|
58616
|
+
return;
|
|
58617
|
+
}
|
|
58618
|
+
throw err;
|
|
58619
|
+
}),
|
|
58620
|
+
serializeTraceCarrier()
|
|
58621
|
+
]);
|
|
58622
|
+
if (stepCompleted409) {
|
|
58623
|
+
return;
|
|
58644
58624
|
}
|
|
58625
|
+
span?.setAttributes({
|
|
58626
|
+
...StepStatus("completed"),
|
|
58627
|
+
...StepResultType(typeof result)
|
|
58628
|
+
});
|
|
58645
58629
|
await queueMessage(world, getWorkflowQueueName(workflowName), {
|
|
58646
58630
|
runId: workflowRunId,
|
|
58647
|
-
traceCarrier
|
|
58631
|
+
traceCarrier,
|
|
58648
58632
|
requestedAt: /* @__PURE__ */ new Date()
|
|
58649
58633
|
});
|
|
58650
58634
|
});
|
|
@@ -58659,7 +58643,7 @@ function workflowEntrypoint(workflowCode2) {
|
|
|
58659
58643
|
await handleHealthCheckMessage(healthCheck2, "workflow");
|
|
58660
58644
|
return;
|
|
58661
58645
|
}
|
|
58662
|
-
const { runId, traceCarrier: traceContext, requestedAt
|
|
58646
|
+
const { runId, traceCarrier: traceContext, requestedAt } = WorkflowInvokePayloadSchema.parse(message_);
|
|
58663
58647
|
const workflowName = metadata.queueName.slice("__wkf_workflow_".length);
|
|
58664
58648
|
const spanLinks = await linkToCurrentContext();
|
|
58665
58649
|
return await withTraceContext(traceContext, async () => {
|
|
@@ -58680,179 +58664,183 @@ function workflowEntrypoint(workflowCode2) {
|
|
|
58680
58664
|
...WorkflowRunId(runId),
|
|
58681
58665
|
...WorkflowTracePropagated(!!traceContext)
|
|
58682
58666
|
});
|
|
58683
|
-
|
|
58684
|
-
|
|
58685
|
-
|
|
58686
|
-
|
|
58687
|
-
|
|
58688
|
-
|
|
58689
|
-
|
|
58690
|
-
specVersion: SPEC_VERSION_CURRENT
|
|
58691
|
-
});
|
|
58692
|
-
if (!result2.run) {
|
|
58693
|
-
throw new WorkflowRuntimeError(`Event creation for 'run_started' did not return the run entity for run "${runId}"`);
|
|
58694
|
-
}
|
|
58695
|
-
workflowRun = result2.run;
|
|
58696
|
-
}
|
|
58697
|
-
if (!workflowRun.startedAt) {
|
|
58698
|
-
throw new WorkflowRuntimeError(`Workflow run "${runId}" has no "startedAt" timestamp`);
|
|
58699
|
-
}
|
|
58700
|
-
workflowStartedAt = +workflowRun.startedAt;
|
|
58701
|
-
span?.setAttributes({
|
|
58702
|
-
...WorkflowRunStatus(workflowRun.status),
|
|
58703
|
-
...WorkflowStartedAt(workflowStartedAt)
|
|
58667
|
+
let workflowStartedAt = -1;
|
|
58668
|
+
let workflowRun = await world.runs.get(runId);
|
|
58669
|
+
try {
|
|
58670
|
+
if (workflowRun.status === "pending") {
|
|
58671
|
+
const result = await world.events.create(runId, {
|
|
58672
|
+
eventType: "run_started",
|
|
58673
|
+
specVersion: SPEC_VERSION_CURRENT
|
|
58704
58674
|
});
|
|
58705
|
-
if (
|
|
58706
|
-
|
|
58707
|
-
workflowRunId: runId,
|
|
58708
|
-
status: workflowRun.status
|
|
58709
|
-
});
|
|
58710
|
-
return;
|
|
58711
|
-
}
|
|
58712
|
-
const events = await getAllWorkflowRunEvents(workflowRun.runId);
|
|
58713
|
-
const now = Date.now();
|
|
58714
|
-
const completedWaitIds = new Set(events.filter((e) => e.eventType === "wait_completed").map((e) => e.correlationId));
|
|
58715
|
-
const waitsToComplete = events.filter((e) => e.eventType === "wait_created" && e.correlationId !== void 0 && !completedWaitIds.has(e.correlationId) && now >= e.eventData.resumeAt.getTime()).map((e) => ({
|
|
58716
|
-
eventType: "wait_completed",
|
|
58717
|
-
specVersion: SPEC_VERSION_CURRENT,
|
|
58718
|
-
correlationId: e.correlationId
|
|
58719
|
-
}));
|
|
58720
|
-
for (const waitEvent of waitsToComplete) {
|
|
58721
|
-
try {
|
|
58722
|
-
const result2 = await world.events.create(runId, waitEvent);
|
|
58723
|
-
events.push(result2.event);
|
|
58724
|
-
} catch (err) {
|
|
58725
|
-
if (WorkflowAPIError.is(err) && err.status === 409) {
|
|
58726
|
-
runtimeLogger.info("Wait already completed, skipping", {
|
|
58727
|
-
workflowRunId: runId,
|
|
58728
|
-
correlationId: waitEvent.correlationId
|
|
58729
|
-
});
|
|
58730
|
-
continue;
|
|
58731
|
-
}
|
|
58732
|
-
throw err;
|
|
58733
|
-
}
|
|
58675
|
+
if (!result.run) {
|
|
58676
|
+
throw new WorkflowRuntimeError(`Event creation for 'run_started' did not return the run entity for run "${runId}"`);
|
|
58734
58677
|
}
|
|
58735
|
-
|
|
58736
|
-
|
|
58737
|
-
|
|
58738
|
-
|
|
58739
|
-
|
|
58740
|
-
|
|
58741
|
-
|
|
58742
|
-
});
|
|
58678
|
+
workflowRun = result.run;
|
|
58679
|
+
}
|
|
58680
|
+
if (!workflowRun.startedAt) {
|
|
58681
|
+
throw new WorkflowRuntimeError(`Workflow run "${runId}" has no "startedAt" timestamp`);
|
|
58682
|
+
}
|
|
58683
|
+
} catch (err) {
|
|
58684
|
+
if (err instanceof WorkflowRuntimeError) {
|
|
58685
|
+
runtimeLogger.error("Fatal runtime error during workflow setup", { workflowRunId: runId, error: err.message });
|
|
58743
58686
|
try {
|
|
58744
58687
|
await world.events.create(runId, {
|
|
58745
|
-
eventType: "
|
|
58688
|
+
eventType: "run_failed",
|
|
58746
58689
|
specVersion: SPEC_VERSION_CURRENT,
|
|
58747
58690
|
eventData: {
|
|
58748
|
-
|
|
58691
|
+
error: {
|
|
58692
|
+
message: err.message,
|
|
58693
|
+
stack: err.stack
|
|
58694
|
+
}
|
|
58749
58695
|
}
|
|
58750
58696
|
});
|
|
58751
|
-
} catch (
|
|
58752
|
-
if (WorkflowAPIError.is(
|
|
58753
|
-
runtimeLogger.warn("Tried completing workflow run, but run has already finished.", {
|
|
58754
|
-
workflowRunId: runId,
|
|
58755
|
-
message: err.message
|
|
58756
|
-
});
|
|
58697
|
+
} catch (failErr) {
|
|
58698
|
+
if (WorkflowAPIError.is(failErr) && (failErr.status === 409 || failErr.status === 410)) {
|
|
58757
58699
|
return;
|
|
58758
|
-
} else {
|
|
58759
|
-
throw err;
|
|
58760
58700
|
}
|
|
58701
|
+
throw failErr;
|
|
58761
58702
|
}
|
|
58762
|
-
|
|
58763
|
-
|
|
58764
|
-
|
|
58765
|
-
|
|
58703
|
+
return;
|
|
58704
|
+
}
|
|
58705
|
+
throw err;
|
|
58706
|
+
}
|
|
58707
|
+
workflowStartedAt = +workflowRun.startedAt;
|
|
58708
|
+
span?.setAttributes({
|
|
58709
|
+
...WorkflowRunStatus(workflowRun.status),
|
|
58710
|
+
...WorkflowStartedAt(workflowStartedAt)
|
|
58711
|
+
});
|
|
58712
|
+
if (workflowRun.status !== "running") {
|
|
58713
|
+
runtimeLogger.info("Workflow already completed or failed, skipping", {
|
|
58714
|
+
workflowRunId: runId,
|
|
58715
|
+
status: workflowRun.status
|
|
58716
|
+
});
|
|
58717
|
+
return;
|
|
58718
|
+
}
|
|
58719
|
+
const events = await getAllWorkflowRunEvents(workflowRun.runId);
|
|
58720
|
+
const now = Date.now();
|
|
58721
|
+
const completedWaitIds = new Set(events.filter((e) => e.eventType === "wait_completed").map((e) => e.correlationId));
|
|
58722
|
+
const waitsToComplete = events.filter((e) => e.eventType === "wait_created" && e.correlationId !== void 0 && !completedWaitIds.has(e.correlationId) && now >= e.eventData.resumeAt.getTime()).map((e) => ({
|
|
58723
|
+
eventType: "wait_completed",
|
|
58724
|
+
specVersion: SPEC_VERSION_CURRENT,
|
|
58725
|
+
correlationId: e.correlationId
|
|
58726
|
+
}));
|
|
58727
|
+
for (const waitEvent of waitsToComplete) {
|
|
58728
|
+
try {
|
|
58729
|
+
const result = await world.events.create(runId, waitEvent);
|
|
58730
|
+
events.push(result.event);
|
|
58766
58731
|
} catch (err) {
|
|
58767
|
-
if (
|
|
58768
|
-
|
|
58769
|
-
|
|
58770
|
-
|
|
58771
|
-
}
|
|
58772
|
-
const result = await handleSuspension({
|
|
58773
|
-
suspension: err,
|
|
58774
|
-
world,
|
|
58775
|
-
run: workflowRun,
|
|
58776
|
-
span
|
|
58732
|
+
if (WorkflowAPIError.is(err) && err.status === 409) {
|
|
58733
|
+
runtimeLogger.info("Wait already completed, skipping", {
|
|
58734
|
+
workflowRunId: runId,
|
|
58735
|
+
correlationId: waitEvent.correlationId
|
|
58777
58736
|
});
|
|
58778
|
-
|
|
58779
|
-
|
|
58780
|
-
|
|
58781
|
-
|
|
58782
|
-
|
|
58783
|
-
|
|
58784
|
-
|
|
58785
|
-
|
|
58786
|
-
|
|
58787
|
-
|
|
58788
|
-
|
|
58789
|
-
|
|
58790
|
-
|
|
58791
|
-
|
|
58792
|
-
|
|
58793
|
-
|
|
58794
|
-
|
|
58795
|
-
|
|
58796
|
-
|
|
58797
|
-
|
|
58798
|
-
|
|
58737
|
+
continue;
|
|
58738
|
+
}
|
|
58739
|
+
throw err;
|
|
58740
|
+
}
|
|
58741
|
+
}
|
|
58742
|
+
const rawKey = await world.getEncryptionKeyForRun?.(workflowRun);
|
|
58743
|
+
const encryptionKey = rawKey ? await importKey(rawKey) : void 0;
|
|
58744
|
+
let workflowResult;
|
|
58745
|
+
try {
|
|
58746
|
+
workflowResult = await trace2("workflow.replay", {}, async (replaySpan) => {
|
|
58747
|
+
replaySpan?.setAttributes({
|
|
58748
|
+
...WorkflowEventsCount(events.length)
|
|
58749
|
+
});
|
|
58750
|
+
return await runWorkflow(workflowCode2, workflowRun, events, encryptionKey);
|
|
58751
|
+
});
|
|
58752
|
+
} catch (err) {
|
|
58753
|
+
if (WorkflowSuspension.is(err)) {
|
|
58754
|
+
const suspensionMessage = buildWorkflowSuspensionMessage(runId, err.stepCount, err.hookCount, err.waitCount);
|
|
58755
|
+
if (suspensionMessage) {
|
|
58756
|
+
runtimeLogger.debug(suspensionMessage);
|
|
58757
|
+
}
|
|
58758
|
+
const result = await handleSuspension({
|
|
58759
|
+
suspension: err,
|
|
58760
|
+
world,
|
|
58761
|
+
run: workflowRun,
|
|
58762
|
+
span
|
|
58763
|
+
});
|
|
58764
|
+
if (result.timeoutSeconds !== void 0) {
|
|
58765
|
+
return { timeoutSeconds: result.timeoutSeconds };
|
|
58766
|
+
}
|
|
58767
|
+
return;
|
|
58768
|
+
}
|
|
58769
|
+
if (err instanceof Error) {
|
|
58770
|
+
span?.recordException?.(err);
|
|
58771
|
+
}
|
|
58772
|
+
const normalizedError = await normalizeUnknownError(err);
|
|
58773
|
+
const errorName = normalizedError.name || getErrorName(err);
|
|
58774
|
+
const errorMessage = normalizedError.message;
|
|
58775
|
+
let errorStack = normalizedError.stack || getErrorStack(err);
|
|
58776
|
+
if (errorStack) {
|
|
58777
|
+
const parsedName = parseWorkflowName(workflowName);
|
|
58778
|
+
const filename = parsedName?.moduleSpecifier || workflowName;
|
|
58779
|
+
errorStack = remapErrorStack(errorStack, filename, workflowCode2);
|
|
58780
|
+
}
|
|
58781
|
+
runtimeLogger.error("Error while running workflow", {
|
|
58782
|
+
workflowRunId: runId,
|
|
58783
|
+
errorName,
|
|
58784
|
+
errorStack
|
|
58785
|
+
});
|
|
58786
|
+
try {
|
|
58787
|
+
await world.events.create(runId, {
|
|
58788
|
+
eventType: "run_failed",
|
|
58789
|
+
specVersion: SPEC_VERSION_CURRENT,
|
|
58790
|
+
eventData: {
|
|
58791
|
+
error: {
|
|
58792
|
+
message: errorMessage,
|
|
58793
|
+
stack: errorStack
|
|
58799
58794
|
}
|
|
58800
|
-
|
|
58801
|
-
throw err;
|
|
58795
|
+
// TODO: include error codes when we define them
|
|
58802
58796
|
}
|
|
58803
|
-
|
|
58804
|
-
|
|
58805
|
-
|
|
58806
|
-
|
|
58807
|
-
const errorName = normalizedError.name || getErrorName(err);
|
|
58808
|
-
const errorMessage = normalizedError.message;
|
|
58809
|
-
let errorStack = normalizedError.stack || getErrorStack(err);
|
|
58810
|
-
if (errorStack) {
|
|
58811
|
-
const parsedName = parseWorkflowName(workflowName);
|
|
58812
|
-
const filename = parsedName?.moduleSpecifier || workflowName;
|
|
58813
|
-
errorStack = remapErrorStack(errorStack, filename, workflowCode2);
|
|
58814
|
-
}
|
|
58815
|
-
runtimeLogger.error("Error while running workflow", {
|
|
58797
|
+
});
|
|
58798
|
+
} catch (failErr) {
|
|
58799
|
+
if (WorkflowAPIError.is(failErr) && (failErr.status === 409 || failErr.status === 410)) {
|
|
58800
|
+
runtimeLogger.warn("Tried failing workflow run, but run has already finished.", {
|
|
58816
58801
|
workflowRunId: runId,
|
|
58817
|
-
|
|
58818
|
-
errorStack
|
|
58802
|
+
message: failErr.message
|
|
58819
58803
|
});
|
|
58820
|
-
try {
|
|
58821
|
-
await world.events.create(runId, {
|
|
58822
|
-
eventType: "run_failed",
|
|
58823
|
-
specVersion: SPEC_VERSION_CURRENT,
|
|
58824
|
-
eventData: {
|
|
58825
|
-
error: {
|
|
58826
|
-
message: errorMessage,
|
|
58827
|
-
stack: errorStack
|
|
58828
|
-
}
|
|
58829
|
-
// TODO: include error codes when we define them
|
|
58830
|
-
}
|
|
58831
|
-
});
|
|
58832
|
-
} catch (err2) {
|
|
58833
|
-
if (WorkflowAPIError.is(err2) && (err2.status === 409 || err2.status === 410)) {
|
|
58834
|
-
runtimeLogger.warn("Tried failing workflow run, but run has already finished.", {
|
|
58835
|
-
workflowRunId: runId,
|
|
58836
|
-
message: err2.message
|
|
58837
|
-
});
|
|
58838
|
-
span?.setAttributes({
|
|
58839
|
-
...WorkflowErrorName(errorName),
|
|
58840
|
-
...WorkflowErrorMessage(errorMessage),
|
|
58841
|
-
...ErrorType(errorName)
|
|
58842
|
-
});
|
|
58843
|
-
return;
|
|
58844
|
-
} else {
|
|
58845
|
-
throw err2;
|
|
58846
|
-
}
|
|
58847
|
-
}
|
|
58848
58804
|
span?.setAttributes({
|
|
58849
|
-
...WorkflowRunStatus("failed"),
|
|
58850
58805
|
...WorkflowErrorName(errorName),
|
|
58851
58806
|
...WorkflowErrorMessage(errorMessage),
|
|
58852
58807
|
...ErrorType(errorName)
|
|
58853
58808
|
});
|
|
58809
|
+
return;
|
|
58810
|
+
} else {
|
|
58811
|
+
throw failErr;
|
|
58812
|
+
}
|
|
58813
|
+
}
|
|
58814
|
+
span?.setAttributes({
|
|
58815
|
+
...WorkflowRunStatus("failed"),
|
|
58816
|
+
...WorkflowErrorName(errorName),
|
|
58817
|
+
...WorkflowErrorMessage(errorMessage),
|
|
58818
|
+
...ErrorType(errorName)
|
|
58819
|
+
});
|
|
58820
|
+
return;
|
|
58821
|
+
}
|
|
58822
|
+
try {
|
|
58823
|
+
await world.events.create(runId, {
|
|
58824
|
+
eventType: "run_completed",
|
|
58825
|
+
specVersion: SPEC_VERSION_CURRENT,
|
|
58826
|
+
eventData: {
|
|
58827
|
+
output: workflowResult
|
|
58854
58828
|
}
|
|
58829
|
+
});
|
|
58830
|
+
} catch (err) {
|
|
58831
|
+
if (WorkflowAPIError.is(err) && (err.status === 409 || err.status === 410)) {
|
|
58832
|
+
runtimeLogger.warn("Tried completing workflow run, but run has already finished.", {
|
|
58833
|
+
workflowRunId: runId,
|
|
58834
|
+
message: err.message
|
|
58835
|
+
});
|
|
58836
|
+
return;
|
|
58837
|
+
} else {
|
|
58838
|
+
throw err;
|
|
58855
58839
|
}
|
|
58840
|
+
}
|
|
58841
|
+
span?.setAttributes({
|
|
58842
|
+
...WorkflowRunStatus("completed"),
|
|
58843
|
+
...WorkflowEventsCount(events.length)
|
|
58856
58844
|
});
|
|
58857
58845
|
});
|
|
58858
58846
|
});
|
|
@@ -59090,7 +59078,7 @@ function getWritable(options = {}) {
|
|
|
59090
59078
|
__name(getWritable, "getWritable");
|
|
59091
59079
|
|
|
59092
59080
|
// ../workflow/dist/stdlib.js
|
|
59093
|
-
var fetch = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//workflow@4.2.0-beta.
|
|
59081
|
+
var fetch = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//workflow@4.2.0-beta.70//fetch");
|
|
59094
59082
|
|
|
59095
59083
|
// ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/core.js
|
|
59096
59084
|
var NEVER = Object.freeze({
|