@workflow/world-testing 4.1.7 → 4.1.8

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.
@@ -48723,7 +48723,7 @@ init_dist();
48723
48723
  init_node();
48724
48724
 
48725
48725
  // ../core/dist/version.js
48726
- var version2 = "4.3.0";
48726
+ var version2 = "4.3.1";
48727
48727
 
48728
48728
  // ../core/dist/runtime/world.js
48729
48729
  var import_node_module = require("node:module");
@@ -58332,7 +58332,7 @@ var import_oidc3 = __toESM(require_dist(), 1);
58332
58332
  init_dist();
58333
58333
 
58334
58334
  // ../world-vercel/dist/version.js
58335
- var version3 = "4.3.1";
58335
+ var version3 = "4.3.2";
58336
58336
 
58337
58337
  // ../world-vercel/dist/utils.js
58338
58338
  var HTTP_DEBUG_ENABLED = typeof process !== "undefined" && typeof process.env.DEBUG === "string" && (process.env.DEBUG.includes("workflow:") || process.env.DEBUG === "*");
@@ -58343,6 +58343,10 @@ function httpLog(method, endpoint, status, ms2) {
58343
58343
  }
58344
58344
  __name(httpLog, "httpLog");
58345
58345
  var WORKFLOW_SERVER_URL_OVERRIDE = "";
58346
+ var REQUEST_TIMEOUT_MS = 6e4;
58347
+ var IDEMPOTENT_METHODS = /* @__PURE__ */ new Set(["GET", "HEAD"]);
58348
+ var MAX_BODY_PARSE_RETRIES = 2;
58349
+ var BODY_PARSE_RETRY_BASE_MS = 100;
58346
58350
  var getWorkflowServerUrlOverride = /* @__PURE__ */ __name(() => WORKFLOW_SERVER_URL_OVERRIDE || process.env.VERCEL_WORKFLOW_SERVER_URL || "", "getWorkflowServerUrlOverride");
58347
58351
  var DEFAULT_RESOLVE_DATA_OPTION2 = "all";
58348
58352
  function deserializeError(obj) {
@@ -58471,85 +58475,115 @@ async function makeRequest({ endpoint, options = {}, config: config3 = {}, schem
58471
58475
  ...RpcService3("workflow-server")
58472
58476
  });
58473
58477
  headers.set("Accept", "application/cbor");
58474
- headers.set("X-Request-Time", Date.now().toString());
58475
58478
  let body;
58476
58479
  if (data !== void 0) {
58477
58480
  headers.set("Content-Type", "application/cbor");
58478
58481
  body = encode3(data);
58479
58482
  }
58480
- const request = new Request(url2, {
58481
- ...options,
58482
- body,
58483
- headers
58484
- });
58485
- const fetchStart = Date.now();
58486
- const response = await fetch(request, {
58487
- dispatcher: getDispatcher()
58488
- });
58489
- const fetchMs = Date.now() - fetchStart;
58490
- httpLog(method, endpoint, response.status, fetchMs);
58491
- span?.setAttributes({
58492
- ...HttpResponseStatusCode2(response.status)
58493
- });
58494
- if (!response.ok) {
58495
- const errorData = await parseResponseBody(response).then((r) => r.data).catch(() => ({}));
58496
- if (process.env.DEBUG) {
58497
- const stringifiedHeaders = Array.from(headers.entries()).filter(([key]) => key.toLowerCase() !== "authorization").map(([key, value]) => `-H "${key}: ${value}"`).join(" ");
58498
- console.error(`Failed to fetch, reproduce with:
58499
- curl -X ${request.method} ${stringifiedHeaders} "${url2}"`);
58500
- }
58501
- let retryAfter;
58502
- const retryAfterHeader = response.headers.get("Retry-After");
58503
- if (retryAfterHeader) {
58504
- const parsed = parseInt(retryAfterHeader, 10);
58505
- if (!Number.isNaN(parsed)) {
58506
- retryAfter = parsed;
58507
- }
58508
- }
58509
- const defaultMessage = errorData.message || `${request.method} ${endpoint} -> HTTP ${response.status}: ${response.statusText}`;
58510
- const throwWithTrace = /* @__PURE__ */ __name((error48) => {
58511
- span?.setAttributes({
58512
- ...ErrorType2(errorData.code || `HTTP ${response.status}`)
58483
+ const canRetryBody = IDEMPOTENT_METHODS.has(method.toUpperCase());
58484
+ let parseResult;
58485
+ for (let attempt = 0; ; attempt++) {
58486
+ headers.set("X-Request-Time", Date.now().toString());
58487
+ const timeoutSignal = AbortSignal.timeout(REQUEST_TIMEOUT_MS);
58488
+ const signal = options.signal ? AbortSignal.any([options.signal, timeoutSignal]) : timeoutSignal;
58489
+ const request = new Request(url2, {
58490
+ ...options,
58491
+ body,
58492
+ headers,
58493
+ signal
58494
+ });
58495
+ const fetchStart = Date.now();
58496
+ let response;
58497
+ try {
58498
+ response = await fetch(request, {
58499
+ dispatcher: getDispatcher()
58513
58500
  });
58514
- span?.recordException?.(error48);
58501
+ } catch (error48) {
58502
+ const elapsed = Date.now() - fetchStart;
58503
+ if (error48 instanceof Error && (error48.name === "TimeoutError" || error48.name === "AbortError")) {
58504
+ const timeoutError = new WorkflowWorldError(`${method} ${endpoint} timed out after ${elapsed}ms`, { url: url2, cause: error48 });
58505
+ span?.setAttributes({ ...ErrorType2("TIMEOUT") });
58506
+ span?.recordException?.(timeoutError);
58507
+ throw timeoutError;
58508
+ }
58515
58509
  throw error48;
58516
- }, "throwWithTrace");
58517
- if (response.status === 409) {
58518
- throwWithTrace(new EntityConflictError(defaultMessage));
58519
58510
  }
58520
- if (response.status === 410) {
58521
- throwWithTrace(new RunExpiredError(defaultMessage));
58522
- }
58523
- if (response.status === 425) {
58524
- throwWithTrace(new TooEarlyError(defaultMessage, { retryAfter }));
58525
- }
58526
- if (response.status === 429) {
58527
- throwWithTrace(new ThrottleError(defaultMessage, { retryAfter }));
58511
+ const fetchMs = Date.now() - fetchStart;
58512
+ httpLog(method, endpoint, response.status, fetchMs);
58513
+ span?.setAttributes({
58514
+ ...HttpResponseStatusCode2(response.status)
58515
+ });
58516
+ if (!response.ok) {
58517
+ const errorData = await parseResponseBody(response).then((r) => r.data).catch(() => ({}));
58518
+ if (process.env.DEBUG) {
58519
+ const stringifiedHeaders = Array.from(headers.entries()).filter(([key]) => key.toLowerCase() !== "authorization").map(([key, value]) => `-H "${key}: ${value}"`).join(" ");
58520
+ console.error(`Failed to fetch, reproduce with:
58521
+ curl -X ${request.method} ${stringifiedHeaders} "${url2}"`);
58522
+ }
58523
+ let retryAfter;
58524
+ const retryAfterHeader = response.headers.get("Retry-After");
58525
+ if (retryAfterHeader) {
58526
+ const parsed = parseInt(retryAfterHeader, 10);
58527
+ if (!Number.isNaN(parsed)) {
58528
+ retryAfter = parsed;
58529
+ }
58530
+ }
58531
+ const defaultMessage = errorData.message || `${request.method} ${endpoint} -> HTTP ${response.status}: ${response.statusText}`;
58532
+ const throwWithTrace = /* @__PURE__ */ __name((error48) => {
58533
+ span?.setAttributes({
58534
+ ...ErrorType2(errorData.code || `HTTP ${response.status}`)
58535
+ });
58536
+ span?.recordException?.(error48);
58537
+ throw error48;
58538
+ }, "throwWithTrace");
58539
+ if (response.status === 409) {
58540
+ throwWithTrace(new EntityConflictError(defaultMessage));
58541
+ }
58542
+ if (response.status === 410) {
58543
+ throwWithTrace(new RunExpiredError(defaultMessage));
58544
+ }
58545
+ if (response.status === 425) {
58546
+ throwWithTrace(new TooEarlyError(defaultMessage, { retryAfter }));
58547
+ }
58548
+ if (response.status === 429) {
58549
+ throwWithTrace(new ThrottleError(defaultMessage, { retryAfter }));
58550
+ }
58551
+ throwWithTrace(new WorkflowWorldError(defaultMessage, {
58552
+ url: url2,
58553
+ status: response.status,
58554
+ code: errorData.code,
58555
+ retryAfter
58556
+ }));
58528
58557
  }
58529
- throwWithTrace(new WorkflowWorldError(defaultMessage, {
58530
- url: url2,
58531
- status: response.status,
58532
- code: errorData.code,
58533
- retryAfter
58534
- }));
58535
- }
58536
- onResponse?.(response);
58537
- let parseResult;
58538
- try {
58539
- parseResult = await trace4("world.parse", async (parseSpan) => {
58540
- const result2 = await parseResponseBody(response);
58541
- const contentType = response.headers.get("Content-Type") || "";
58542
- const isCbor = contentType.includes("application/cbor");
58543
- parseSpan?.setAttributes({
58544
- ...WorldParseFormat2(isCbor ? "cbor" : "json")
58558
+ onResponse?.(response);
58559
+ try {
58560
+ parseResult = await trace4("world.parse", async (parseSpan) => {
58561
+ const result2 = await parseResponseBody(response);
58562
+ const contentType = response.headers.get("Content-Type") || "";
58563
+ const isCbor = contentType.includes("application/cbor");
58564
+ parseSpan?.setAttributes({
58565
+ ...WorldParseFormat2(isCbor ? "cbor" : "json")
58566
+ });
58567
+ return result2;
58545
58568
  });
58546
- return result2;
58547
- });
58548
- } catch (error48) {
58549
- const contentType = response.headers.get("Content-Type") || "unknown";
58550
- throw new WorkflowWorldError(`Failed to parse response body for ${request.method} ${endpoint} (Content-Type: ${contentType}):
58569
+ break;
58570
+ } catch (error48) {
58571
+ if (canRetryBody && attempt < MAX_BODY_PARSE_RETRIES) {
58572
+ const backoffMs = BODY_PARSE_RETRY_BASE_MS * 2 ** attempt;
58573
+ span?.setAttributes({
58574
+ ...ErrorType2("PARSE_ERROR_RETRYING")
58575
+ });
58576
+ if (HTTP_DEBUG_ENABLED) {
58577
+ console.debug(`[workflow:world-vercel:http] ${method} ${endpoint} body parse failed (attempt ${attempt + 1}/${MAX_BODY_PARSE_RETRIES + 1}); retrying in ${backoffMs}ms: ${error48}`);
58578
+ }
58579
+ await new Promise((resolve3) => setTimeout(resolve3, backoffMs));
58580
+ continue;
58581
+ }
58582
+ const contentType = response.headers.get("Content-Type") || "unknown";
58583
+ throw new WorkflowWorldError(`Failed to parse response body for ${method} ${endpoint} (Content-Type: ${contentType}):
58551
58584
 
58552
58585
  ${error48}`, { url: url2, code: "PARSE_ERROR", cause: error48 });
58586
+ }
58553
58587
  }
58554
58588
  const result = await trace4("world.validate", async () => {
58555
58589
  const validationResult = schema.safeParse(parseResult.data);
@@ -6,11 +6,6 @@
6
6
  "stepId": "step//./workflows/null-byte//nullByteStep"
7
7
  }
8
8
  },
9
- "workflows/hooks.ts": {
10
- "writeEvent": {
11
- "stepId": "step//./workflows/hooks//writeEvent"
12
- }
13
- },
14
9
  "workflows/retriable-and-fatal.ts": {
15
10
  "stepThatFails": {
16
11
  "stepId": "step//./workflows/retriable-and-fatal//stepThatFails"
@@ -19,6 +14,21 @@
19
14
  "stepId": "step//./workflows/retriable-and-fatal//stepThatThrowsRetryableError"
20
15
  }
21
16
  },
17
+ "workflows/addition.ts": {
18
+ "add": {
19
+ "stepId": "step//./workflows/addition//add"
20
+ }
21
+ },
22
+ "workflows/hooks.ts": {
23
+ "writeEvent": {
24
+ "stepId": "step//./workflows/hooks//writeEvent"
25
+ }
26
+ },
27
+ "workflows/noop.ts": {
28
+ "noop": {
29
+ "stepId": "step//./workflows/noop//noop"
30
+ }
31
+ },
22
32
  "workflow/dist/internal/builtins.js": {
23
33
  "__builtin_response_array_buffer": {
24
34
  "stepId": "__builtin_response_array_buffer"
@@ -29,16 +39,6 @@
29
39
  "__builtin_response_text": {
30
40
  "stepId": "__builtin_response_text"
31
41
  }
32
- },
33
- "workflows/addition.ts": {
34
- "add": {
35
- "stepId": "step//./workflows/addition//add"
36
- }
37
- },
38
- "workflows/noop.ts": {
39
- "noop": {
40
- "stepId": "step//./workflows/noop//noop"
41
- }
42
42
  }
43
43
  },
44
44
  "workflows": {
@@ -75,16 +75,16 @@
75
75
  }
76
76
  }
77
77
  },
78
- "workflows/hooks.ts": {
79
- "collectWithHook": {
80
- "workflowId": "workflow//./workflows/hooks//collectWithHook",
78
+ "workflows/retriable-and-fatal.ts": {
79
+ "retryableAndFatalErrorWorkflow": {
80
+ "workflowId": "workflow//./workflows/retriable-and-fatal//retryableAndFatalErrorWorkflow",
81
81
  "graph": {
82
82
  "nodes": [
83
83
  {
84
84
  "id": "start",
85
85
  "type": "workflowStart",
86
86
  "data": {
87
- "label": "Start: collectWithHook",
87
+ "label": "Start: retryableAndFatalErrorWorkflow",
88
88
  "nodeKind": "workflow_start"
89
89
  }
90
90
  },
@@ -108,16 +108,16 @@
108
108
  }
109
109
  }
110
110
  },
111
- "workflows/retriable-and-fatal.ts": {
112
- "retryableAndFatalErrorWorkflow": {
113
- "workflowId": "workflow//./workflows/retriable-and-fatal//retryableAndFatalErrorWorkflow",
111
+ "workflows/addition.ts": {
112
+ "addition": {
113
+ "workflowId": "workflow//./workflows/addition//addition",
114
114
  "graph": {
115
115
  "nodes": [
116
116
  {
117
117
  "id": "start",
118
118
  "type": "workflowStart",
119
119
  "data": {
120
- "label": "Start: retryableAndFatalErrorWorkflow",
120
+ "label": "Start: addition",
121
121
  "nodeKind": "workflow_start"
122
122
  }
123
123
  },
@@ -141,16 +141,16 @@
141
141
  }
142
142
  }
143
143
  },
144
- "workflows/addition.ts": {
145
- "addition": {
146
- "workflowId": "workflow//./workflows/addition//addition",
144
+ "workflows/hooks.ts": {
145
+ "collectWithHook": {
146
+ "workflowId": "workflow//./workflows/hooks//collectWithHook",
147
147
  "graph": {
148
148
  "nodes": [
149
149
  {
150
150
  "id": "start",
151
151
  "type": "workflowStart",
152
152
  "data": {
153
- "label": "Start: addition",
153
+ "label": "Start: collectWithHook",
154
154
  "nodeKind": "workflow_start"
155
155
  }
156
156
  },