@rivetkit/workflow-engine 2.1.11-rc.1 → 2.2.1-pr.4600.0c0c39c

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.
@@ -1658,7 +1658,19 @@ var DEFAULT_RETRY_BACKOFF_BASE = 100;
1658
1658
  var DEFAULT_RETRY_BACKOFF_MAX = 3e4;
1659
1659
  var DEFAULT_LOOP_HISTORY_PRUNE_INTERVAL = 20;
1660
1660
  var DEFAULT_STEP_TIMEOUT = 3e4;
1661
+ var DEFAULT_TRY_STEP_CATCH = [
1662
+ "critical",
1663
+ "timeout",
1664
+ "exhausted"
1665
+ ];
1666
+ var DEFAULT_TRY_BLOCK_CATCH = [
1667
+ "step",
1668
+ "join",
1669
+ "race"
1670
+ ];
1661
1671
  var QUEUE_HISTORY_MESSAGE_MARKER = "__rivetWorkflowQueueMessage";
1672
+ var TRY_STEP_FAILURE_SYMBOL = /* @__PURE__ */ Symbol("workflow.try-step.failure");
1673
+ var TRY_BLOCK_FAILURE_SYMBOL = /* @__PURE__ */ Symbol("workflow.try-block.failure");
1662
1674
  function calculateBackoff(attempts, base, max) {
1663
1675
  return Math.min(max, base * 2 ** attempts);
1664
1676
  }
@@ -1670,6 +1682,128 @@ var StepTimeoutError = class extends Error {
1670
1682
  this.name = "StepTimeoutError";
1671
1683
  }
1672
1684
  };
1685
+ function attachTryStepFailure(error, failure) {
1686
+ error[TRY_STEP_FAILURE_SYMBOL] = failure;
1687
+ return error;
1688
+ }
1689
+ function readTryStepFailure(error) {
1690
+ if (!(error instanceof Error)) {
1691
+ return void 0;
1692
+ }
1693
+ return error[TRY_STEP_FAILURE_SYMBOL];
1694
+ }
1695
+ function attachTryBlockFailure(error, failure) {
1696
+ error[TRY_BLOCK_FAILURE_SYMBOL] = failure;
1697
+ return error;
1698
+ }
1699
+ function readTryBlockFailure(error) {
1700
+ if (!(error instanceof Error)) {
1701
+ return void 0;
1702
+ }
1703
+ return error[TRY_BLOCK_FAILURE_SYMBOL];
1704
+ }
1705
+ function shouldRethrowTryError(error) {
1706
+ return error instanceof StepFailedError || error instanceof SleepError || error instanceof MessageWaitError || error instanceof EvictedError || error instanceof HistoryDivergedError || error instanceof EntryInProgressError || error instanceof RollbackCheckpointError || error instanceof RollbackStopError;
1707
+ }
1708
+ function shouldCatchTryStepFailure(failure, catchKinds) {
1709
+ const effectiveCatch = _nullishCoalesce(catchKinds, () => ( DEFAULT_TRY_STEP_CATCH));
1710
+ return effectiveCatch.includes(failure.kind);
1711
+ }
1712
+ function shouldCatchTryBlockFailure(failure, catchKinds) {
1713
+ var _a;
1714
+ const effectiveCatch = _nullishCoalesce(catchKinds, () => ( DEFAULT_TRY_BLOCK_CATCH));
1715
+ if (failure.source === "step") {
1716
+ return ((_a = failure.step) == null ? void 0 : _a.kind) === "rollback" ? effectiveCatch.includes("rollback") : effectiveCatch.includes("step");
1717
+ }
1718
+ if (failure.source === "join") {
1719
+ return effectiveCatch.includes("join");
1720
+ }
1721
+ if (failure.source === "race") {
1722
+ return effectiveCatch.includes("race");
1723
+ }
1724
+ return effectiveCatch.includes("rollback");
1725
+ }
1726
+ function parseStoredWorkflowError(message) {
1727
+ if (!message) {
1728
+ return {
1729
+ name: "Error",
1730
+ message: "unknown error"
1731
+ };
1732
+ }
1733
+ const match = /^([^:]+):\s*(.*)$/s.exec(message);
1734
+ if (!match) {
1735
+ return {
1736
+ name: "Error",
1737
+ message
1738
+ };
1739
+ }
1740
+ return {
1741
+ name: match[1],
1742
+ message: match[2]
1743
+ };
1744
+ }
1745
+ function getTryStepFailureFromExhaustedError(stepName, attempts, error) {
1746
+ return {
1747
+ kind: "exhausted",
1748
+ stepName,
1749
+ attempts,
1750
+ error: parseStoredWorkflowError(error.lastError)
1751
+ };
1752
+ }
1753
+ function mergeSchedulerYield(state, error) {
1754
+ const nextState = _nullishCoalesce(state, () => ( {
1755
+ messageNames: /* @__PURE__ */ new Set()
1756
+ }));
1757
+ if (error instanceof SleepError) {
1758
+ nextState.deadline = nextState.deadline === void 0 ? error.deadline : Math.min(nextState.deadline, error.deadline);
1759
+ for (const messageName of _nullishCoalesce(error.messageNames, () => ( []))) {
1760
+ nextState.messageNames.add(messageName);
1761
+ }
1762
+ return nextState;
1763
+ }
1764
+ if (error instanceof MessageWaitError) {
1765
+ for (const messageName of error.messageNames) {
1766
+ nextState.messageNames.add(messageName);
1767
+ }
1768
+ return nextState;
1769
+ }
1770
+ nextState.deadline = nextState.deadline === void 0 ? error.retryAt : Math.min(nextState.deadline, error.retryAt);
1771
+ return nextState;
1772
+ }
1773
+ function buildSchedulerYieldError(state) {
1774
+ const messageNames = [...state.messageNames];
1775
+ if (state.deadline !== void 0) {
1776
+ return new SleepError(
1777
+ state.deadline,
1778
+ messageNames.length > 0 ? messageNames : void 0
1779
+ );
1780
+ }
1781
+ return new MessageWaitError(messageNames);
1782
+ }
1783
+ function controlFlowErrorPriority(error) {
1784
+ if (error instanceof EvictedError) {
1785
+ return 0;
1786
+ }
1787
+ if (error instanceof HistoryDivergedError) {
1788
+ return 1;
1789
+ }
1790
+ if (error instanceof EntryInProgressError) {
1791
+ return 2;
1792
+ }
1793
+ if (error instanceof RollbackCheckpointError) {
1794
+ return 3;
1795
+ }
1796
+ if (error instanceof RollbackStopError) {
1797
+ return 4;
1798
+ }
1799
+ return 5;
1800
+ }
1801
+ function selectControlFlowError(current, candidate) {
1802
+ if (!current) {
1803
+ return candidate;
1804
+ }
1805
+ return controlFlowErrorPriority(candidate) < controlFlowErrorPriority(current) ? candidate : current;
1806
+ }
1673
1807
  var WorkflowContextImpl = (_class = class _WorkflowContextImpl {
1674
1808
  constructor(workflowId, storage, driver, messageDriver, location = emptyLocation(), abortController, mode = "forward", rollbackActions, rollbackCheckpointSet = false, historyNotifier, onError, logger, visitedKeys) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);
1675
1809
  this.workflowId = workflowId;
@@ -1896,6 +2030,110 @@ var WorkflowContextImpl = (_class = class _WorkflowContextImpl {
1896
2030
  this.entryInProgress = false;
1897
2031
  }
1898
2032
  }
2033
+ async tryStep(nameOrConfig, run) {
2034
+ const config2 = typeof nameOrConfig === "string" ? {
2035
+ name: nameOrConfig,
2036
+ run
2037
+ } : nameOrConfig;
2038
+ try {
2039
+ return {
2040
+ ok: true,
2041
+ value: await this.step(config2)
2042
+ };
2043
+ } catch (error) {
2044
+ if (shouldRethrowTryError(error)) {
2045
+ throw error;
2046
+ }
2047
+ const failure = readTryStepFailure(error);
2048
+ if (!failure || !shouldCatchTryStepFailure(failure, config2.catch)) {
2049
+ throw error;
2050
+ }
2051
+ return {
2052
+ ok: false,
2053
+ failure
2054
+ };
2055
+ }
2056
+ }
2057
+ async try(nameOrConfig, run) {
2058
+ this.assertNotInProgress();
2059
+ this.checkEvicted();
2060
+ const config2 = typeof nameOrConfig === "string" ? {
2061
+ name: nameOrConfig,
2062
+ run
2063
+ } : nameOrConfig;
2064
+ this.entryInProgress = true;
2065
+ try {
2066
+ return await this.executeTry(config2);
2067
+ } finally {
2068
+ this.entryInProgress = false;
2069
+ }
2070
+ }
2071
+ async executeTry(config2) {
2072
+ this.checkDuplicateName(config2.name);
2073
+ const location = appendName(
2074
+ this.storage,
2075
+ this.currentLocation,
2076
+ config2.name
2077
+ );
2078
+ const blockCtx = this.createBranch(location);
2079
+ try {
2080
+ const value = await config2.run(blockCtx);
2081
+ blockCtx.validateComplete();
2082
+ return {
2083
+ ok: true,
2084
+ value
2085
+ };
2086
+ } catch (error) {
2087
+ if (shouldRethrowTryError(error)) {
2088
+ throw error;
2089
+ }
2090
+ const stepFailure = readTryStepFailure(error);
2091
+ if (stepFailure) {
2092
+ const failure = {
2093
+ source: "step",
2094
+ name: stepFailure.stepName,
2095
+ error: stepFailure.error,
2096
+ step: stepFailure
2097
+ };
2098
+ if (!shouldCatchTryBlockFailure(failure, config2.catch)) {
2099
+ throw error;
2100
+ }
2101
+ return {
2102
+ ok: false,
2103
+ failure
2104
+ };
2105
+ }
2106
+ const operationFailure = readTryBlockFailure(error);
2107
+ if (operationFailure) {
2108
+ const failure = {
2109
+ ...operationFailure,
2110
+ error: extractErrorInfo(error)
2111
+ };
2112
+ if (!shouldCatchTryBlockFailure(failure, config2.catch)) {
2113
+ throw error;
2114
+ }
2115
+ return {
2116
+ ok: false,
2117
+ failure
2118
+ };
2119
+ }
2120
+ if (error instanceof RollbackError) {
2121
+ const failure = {
2122
+ source: "block",
2123
+ name: config2.name,
2124
+ error: extractErrorInfo(error)
2125
+ };
2126
+ if (!shouldCatchTryBlockFailure(failure, config2.catch)) {
2127
+ throw error;
2128
+ }
2129
+ return {
2130
+ ok: false,
2131
+ failure
2132
+ };
2133
+ }
2134
+ throw error;
2135
+ }
2136
+ }
1899
2137
  async executeStep(config2) {
1900
2138
  this.ensureRollbackCheckpoint(config2);
1901
2139
  if (this.mode === "rollback") {
@@ -1928,9 +2166,19 @@ var WorkflowContextImpl = (_class = class _WorkflowContextImpl {
1928
2166
  const maxRetries2 = _nullishCoalesce(config2.maxRetries, () => ( DEFAULT_MAX_RETRIES));
1929
2167
  if (metadata2.attempts > maxRetries2) {
1930
2168
  const lastError = _nullishCoalesce(stepData.error, () => ( metadata2.error));
1931
- const exhaustedError = markErrorReported(
1932
- new StepExhaustedError(config2.name, lastError)
2169
+ const exhaustedError = new StepExhaustedError(
2170
+ config2.name,
2171
+ lastError
1933
2172
  );
2173
+ attachTryStepFailure(
2174
+ exhaustedError,
2175
+ getTryStepFailureFromExhaustedError(
2176
+ config2.name,
2177
+ metadata2.attempts,
2178
+ exhaustedError
2179
+ )
2180
+ );
2181
+ markErrorReported(exhaustedError);
1934
2182
  if (metadata2.status !== "exhausted") {
1935
2183
  metadata2.status = "exhausted";
1936
2184
  metadata2.dirty = true;
@@ -2017,7 +2265,17 @@ var WorkflowContextImpl = (_class = class _WorkflowContextImpl {
2017
2265
  await this.notifyStepError(config2, metadata.attempts, error, {
2018
2266
  willRetry: false
2019
2267
  });
2020
- throw markErrorReported(new CriticalError(error.message));
2268
+ throw markErrorReported(
2269
+ attachTryStepFailure(
2270
+ new CriticalError(error.message),
2271
+ {
2272
+ kind: "timeout",
2273
+ stepName: config2.name,
2274
+ attempts: metadata.attempts,
2275
+ error: extractErrorInfo(error)
2276
+ }
2277
+ )
2278
+ );
2021
2279
  }
2022
2280
  if (error instanceof CriticalError || error instanceof RollbackError) {
2023
2281
  if (entry.kind.type === "step") {
@@ -2030,7 +2288,14 @@ var WorkflowContextImpl = (_class = class _WorkflowContextImpl {
2030
2288
  await this.notifyStepError(config2, metadata.attempts, error, {
2031
2289
  willRetry: false
2032
2290
  });
2033
- throw markErrorReported(error);
2291
+ throw markErrorReported(
2292
+ attachTryStepFailure(error, {
2293
+ kind: error instanceof RollbackError ? "rollback" : "critical",
2294
+ stepName: config2.name,
2295
+ attempts: metadata.attempts,
2296
+ error: extractErrorInfo(error)
2297
+ })
2298
+ );
2034
2299
  }
2035
2300
  if (entry.kind.type === "step") {
2036
2301
  entry.kind.data.error = String(error);
@@ -2060,7 +2325,15 @@ var WorkflowContextImpl = (_class = class _WorkflowContextImpl {
2060
2325
  );
2061
2326
  }
2062
2327
  const exhaustedError = markErrorReported(
2063
- new StepExhaustedError(config2.name, String(error))
2328
+ attachTryStepFailure(
2329
+ new StepExhaustedError(config2.name, String(error)),
2330
+ {
2331
+ kind: "exhausted",
2332
+ stepName: config2.name,
2333
+ attempts: metadata.attempts,
2334
+ error: extractErrorInfo(error)
2335
+ }
2336
+ )
2064
2337
  );
2065
2338
  await this.notifyStepError(config2, metadata.attempts, error, {
2066
2339
  willRetry: false
@@ -2835,9 +3108,29 @@ var WorkflowContextImpl = (_class = class _WorkflowContextImpl {
2835
3108
  const joinData = entry.kind.data;
2836
3109
  const results = {};
2837
3110
  const errors = {};
3111
+ let schedulerYieldState;
3112
+ let propagatedError;
3113
+ for (const [branchName, branchStatus] of Object.entries(
3114
+ joinData.branches
3115
+ )) {
3116
+ if (branchStatus.status === "completed") {
3117
+ results[branchName] = branchStatus.output;
3118
+ continue;
3119
+ }
3120
+ if (branchStatus.status === "failed") {
3121
+ errors[branchName] = new Error(
3122
+ _nullishCoalesce(branchStatus.error, () => ( "branch failed"))
3123
+ );
3124
+ }
3125
+ }
2838
3126
  const branchPromises = Object.entries(branches).map(
2839
3127
  async ([branchName, config2]) => {
2840
3128
  const branchStatus = joinData.branches[branchName];
3129
+ if (!branchStatus) {
3130
+ throw new HistoryDivergedError(
3131
+ `Expected join branch "${branchName}" in "${name}"`
3132
+ );
3133
+ }
2841
3134
  if (branchStatus.status === "completed") {
2842
3135
  results[branchName] = branchStatus.output;
2843
3136
  return;
@@ -2853,15 +3146,38 @@ var WorkflowContextImpl = (_class = class _WorkflowContextImpl {
2853
3146
  );
2854
3147
  const branchCtx = this.createBranch(branchLocation);
2855
3148
  branchStatus.status = "running";
3149
+ branchStatus.error = void 0;
2856
3150
  entry.dirty = true;
2857
3151
  try {
2858
3152
  const output = await config2.run(branchCtx);
2859
3153
  branchCtx.validateComplete();
2860
3154
  branchStatus.status = "completed";
2861
3155
  branchStatus.output = output;
3156
+ branchStatus.error = void 0;
2862
3157
  results[branchName] = output;
2863
3158
  } catch (error) {
3159
+ if (error instanceof SleepError || error instanceof MessageWaitError || error instanceof StepFailedError) {
3160
+ schedulerYieldState = mergeSchedulerYield(
3161
+ schedulerYieldState,
3162
+ error
3163
+ );
3164
+ branchStatus.status = "running";
3165
+ branchStatus.error = void 0;
3166
+ entry.dirty = true;
3167
+ return;
3168
+ }
3169
+ if (error instanceof EvictedError || error instanceof HistoryDivergedError || error instanceof EntryInProgressError || error instanceof RollbackCheckpointError || error instanceof RollbackStopError) {
3170
+ propagatedError = selectControlFlowError(
3171
+ propagatedError,
3172
+ error
3173
+ );
3174
+ branchStatus.status = "running";
3175
+ branchStatus.error = void 0;
3176
+ entry.dirty = true;
3177
+ return;
3178
+ }
2864
3179
  branchStatus.status = "failed";
3180
+ branchStatus.output = void 0;
2865
3181
  branchStatus.error = String(error);
2866
3182
  errors[branchName] = error;
2867
3183
  }
@@ -2870,8 +3186,24 @@ var WorkflowContextImpl = (_class = class _WorkflowContextImpl {
2870
3186
  );
2871
3187
  await Promise.allSettled(branchPromises);
2872
3188
  await this.flushStorage();
3189
+ if (propagatedError) {
3190
+ throw propagatedError;
3191
+ }
3192
+ if (Object.values(joinData.branches).some(
3193
+ (branch) => branch.status === "pending" || branch.status === "running"
3194
+ )) {
3195
+ if (!schedulerYieldState) {
3196
+ throw new Error(
3197
+ `Join "${name}" has pending branches without a scheduler yield`
3198
+ );
3199
+ }
3200
+ throw buildSchedulerYieldError(schedulerYieldState);
3201
+ }
2873
3202
  if (Object.keys(errors).length > 0) {
2874
- throw new JoinError(errors);
3203
+ throw attachTryBlockFailure(new JoinError(errors), {
3204
+ source: "join",
3205
+ name
3206
+ });
2875
3207
  }
2876
3208
  return results;
2877
3209
  }
@@ -2934,28 +3266,42 @@ var WorkflowContextImpl = (_class = class _WorkflowContextImpl {
2934
3266
  const raceAbortController = new AbortController();
2935
3267
  const branchPromises = [];
2936
3268
  let winnerName = null;
2937
- let winnerValue = null;
2938
- let settled = false;
2939
- let pendingCount = branches.length;
3269
+ let winnerValue;
3270
+ let hasWinner = false;
2940
3271
  const errors = {};
2941
3272
  const lateErrors = [];
2942
- let yieldError = null;
3273
+ let schedulerYieldState;
3274
+ let propagatedError;
2943
3275
  for (const branch of branches) {
2944
3276
  const branchStatus = raceData.branches[branch.name];
3277
+ if (!branchStatus) {
3278
+ throw new HistoryDivergedError(
3279
+ `Expected race branch "${branch.name}" in "${name}"`
3280
+ );
3281
+ }
2945
3282
  if (branchStatus.status !== "pending" && branchStatus.status !== "running") {
2946
- pendingCount--;
2947
- if (branchStatus.status === "completed" && !settled) {
2948
- settled = true;
3283
+ if (branchStatus.status === "failed") {
3284
+ errors[branch.name] = new Error(
3285
+ _nullishCoalesce(branchStatus.error, () => ( "branch failed"))
3286
+ );
3287
+ }
3288
+ if (branchStatus.status === "completed" && !hasWinner) {
3289
+ hasWinner = true;
2949
3290
  winnerName = branch.name;
2950
3291
  winnerValue = branchStatus.output;
2951
3292
  }
2952
3293
  }
2953
3294
  }
2954
- if (settled && winnerName !== null && winnerValue !== null) {
3295
+ if (hasWinner && winnerName !== null) {
2955
3296
  return { winner: winnerName, value: winnerValue };
2956
3297
  }
2957
3298
  for (const branch of branches) {
2958
3299
  const branchStatus = raceData.branches[branch.name];
3300
+ if (!branchStatus) {
3301
+ throw new HistoryDivergedError(
3302
+ `Expected race branch "${branch.name}" in "${name}"`
3303
+ );
3304
+ }
2959
3305
  if (branchStatus.status !== "pending" && branchStatus.status !== "running") {
2960
3306
  continue;
2961
3307
  }
@@ -2969,78 +3315,98 @@ var WorkflowContextImpl = (_class = class _WorkflowContextImpl {
2969
3315
  raceAbortController
2970
3316
  );
2971
3317
  branchStatus.status = "running";
3318
+ branchStatus.error = void 0;
2972
3319
  entry.dirty = true;
2973
3320
  const branchPromise = branch.run(branchCtx).then(
2974
3321
  async (output) => {
2975
- if (settled) {
3322
+ if (hasWinner) {
3323
+ branchStatus.status = "completed";
3324
+ branchStatus.output = output;
3325
+ branchStatus.error = void 0;
3326
+ entry.dirty = true;
3327
+ return;
3328
+ }
3329
+ if (propagatedError) {
2976
3330
  branchStatus.status = "completed";
2977
3331
  branchStatus.output = output;
3332
+ branchStatus.error = void 0;
2978
3333
  entry.dirty = true;
2979
3334
  return;
2980
3335
  }
2981
- settled = true;
3336
+ hasWinner = true;
2982
3337
  winnerName = branch.name;
2983
3338
  winnerValue = output;
2984
3339
  branchCtx.validateComplete();
2985
3340
  branchStatus.status = "completed";
2986
3341
  branchStatus.output = output;
3342
+ branchStatus.error = void 0;
2987
3343
  raceData.winner = branch.name;
2988
3344
  entry.dirty = true;
2989
3345
  raceAbortController.abort();
2990
3346
  },
2991
3347
  (error) => {
2992
- pendingCount--;
2993
- if (error instanceof SleepError) {
2994
- if (!yieldError || !(yieldError instanceof SleepError) || error.deadline < yieldError.deadline) {
2995
- yieldError = error;
3348
+ if (hasWinner) {
3349
+ if (error instanceof CancelledError || error instanceof EvictedError) {
3350
+ branchStatus.status = "cancelled";
3351
+ } else {
3352
+ lateErrors.push({
3353
+ name: branch.name,
3354
+ error: String(error)
3355
+ });
2996
3356
  }
3357
+ entry.dirty = true;
3358
+ return;
3359
+ }
3360
+ if (error instanceof SleepError || error instanceof MessageWaitError || error instanceof StepFailedError) {
3361
+ schedulerYieldState = mergeSchedulerYield(
3362
+ schedulerYieldState,
3363
+ error
3364
+ );
2997
3365
  branchStatus.status = "running";
3366
+ branchStatus.error = void 0;
2998
3367
  entry.dirty = true;
2999
3368
  return;
3000
3369
  }
3001
- if (error instanceof MessageWaitError) {
3002
- if (!yieldError || !(yieldError instanceof SleepError)) {
3003
- if (!yieldError) {
3004
- yieldError = error;
3005
- } else if (yieldError instanceof MessageWaitError) {
3006
- yieldError = new MessageWaitError([
3007
- ...yieldError.messageNames,
3008
- ...error.messageNames
3009
- ]);
3010
- }
3011
- }
3370
+ if (error instanceof EvictedError || error instanceof HistoryDivergedError || error instanceof EntryInProgressError || error instanceof RollbackCheckpointError || error instanceof RollbackStopError) {
3371
+ propagatedError = selectControlFlowError(
3372
+ propagatedError,
3373
+ error
3374
+ );
3012
3375
  branchStatus.status = "running";
3376
+ branchStatus.error = void 0;
3013
3377
  entry.dirty = true;
3014
3378
  return;
3015
3379
  }
3016
- if (error instanceof CancelledError || error instanceof EvictedError) {
3380
+ if (error instanceof CancelledError) {
3017
3381
  branchStatus.status = "cancelled";
3018
3382
  } else {
3019
3383
  branchStatus.status = "failed";
3384
+ branchStatus.output = void 0;
3020
3385
  branchStatus.error = String(error);
3021
- if (settled) {
3022
- lateErrors.push({
3023
- name: branch.name,
3024
- error: String(error)
3025
- });
3026
- } else {
3027
- errors[branch.name] = error;
3028
- }
3386
+ errors[branch.name] = error;
3029
3387
  }
3030
3388
  entry.dirty = true;
3031
- if (pendingCount === 0 && !settled) {
3032
- settled = true;
3033
- }
3034
3389
  }
3035
3390
  );
3036
3391
  branchPromises.push(branchPromise);
3037
3392
  }
3038
3393
  await Promise.allSettled(branchPromises);
3039
- if (yieldError && !settled) {
3394
+ if (propagatedError) {
3395
+ await this.flushStorage();
3396
+ throw propagatedError;
3397
+ }
3398
+ if (!hasWinner && Object.values(raceData.branches).some(
3399
+ (branch) => branch.status === "pending" || branch.status === "running"
3400
+ )) {
3040
3401
  await this.flushStorage();
3041
- throw yieldError;
3402
+ if (!schedulerYieldState) {
3403
+ throw new Error(
3404
+ `Race "${name}" has pending branches without a scheduler yield`
3405
+ );
3406
+ }
3407
+ throw buildSchedulerYieldError(schedulerYieldState);
3042
3408
  }
3043
- if (winnerName !== null) {
3409
+ if (hasWinner && winnerName !== null) {
3044
3410
  for (const branch of branches) {
3045
3411
  if (branch.name !== winnerName) {
3046
3412
  const branchLocation = appendName(
@@ -3064,15 +3430,21 @@ var WorkflowContextImpl = (_class = class _WorkflowContextImpl {
3064
3430
  lateErrors
3065
3431
  );
3066
3432
  }
3067
- if (winnerName !== null && winnerValue !== null) {
3433
+ if (hasWinner && winnerName !== null) {
3068
3434
  return { winner: winnerName, value: winnerValue };
3069
3435
  }
3070
- throw new RaceError(
3071
- "All branches failed",
3072
- Object.entries(errors).map(([name2, error]) => ({
3073
- name: name2,
3074
- error: String(error)
3075
- }))
3436
+ throw attachTryBlockFailure(
3437
+ new RaceError(
3438
+ "All branches failed",
3439
+ Object.entries(errors).map(([branchName, error]) => ({
3440
+ name: branchName,
3441
+ error: String(error)
3442
+ }))
3443
+ ),
3444
+ {
3445
+ source: "race",
3446
+ name
3447
+ }
3076
3448
  );
3077
3449
  }
3078
3450
  // === Removed ===
@@ -3805,4 +4177,4 @@ async function executeWorkflow(workflowId, workflowFn, input, driver, messageDri
3805
4177
 
3806
4178
 
3807
4179
  exports.extractErrorInfo = extractErrorInfo; exports.CriticalError = CriticalError; exports.RollbackError = RollbackError; exports.RollbackCheckpointError = RollbackCheckpointError; exports.SleepError = SleepError; exports.MessageWaitError = MessageWaitError; exports.EvictedError = EvictedError; exports.HistoryDivergedError = HistoryDivergedError; exports.StepExhaustedError = StepExhaustedError; exports.StepFailedError = StepFailedError; exports.JoinError = JoinError; exports.RaceError = RaceError; exports.CancelledError = CancelledError; exports.EntryInProgressError = EntryInProgressError; exports.keyStartsWith = keyStartsWith; exports.compareKeys = compareKeys; exports.keyToHex = keyToHex; exports.isLoopIterationMarker = isLoopIterationMarker; exports.registerName = registerName; exports.resolveName = resolveName; exports.locationToKey = locationToKey; exports.appendName = appendName; exports.appendLoopIteration = appendLoopIteration; exports.emptyLocation = emptyLocation; exports.parentLocation = parentLocation; exports.isLocationPrefix = isLocationPrefix; exports.locationsEqual = locationsEqual; exports.createStorage = createStorage; exports.createHistorySnapshot = createHistorySnapshot; exports.generateId = generateId; exports.createEntry = createEntry; exports.getOrCreateMetadata = getOrCreateMetadata; exports.loadStorage = loadStorage; exports.loadMetadata = loadMetadata; exports.flush = flush; exports.deleteEntriesWithPrefix = deleteEntriesWithPrefix; exports.getEntry = getEntry; exports.setEntry = setEntry; exports.sleep = sleep; exports.DEFAULT_MAX_RETRIES = DEFAULT_MAX_RETRIES; exports.DEFAULT_RETRY_BACKOFF_BASE = DEFAULT_RETRY_BACKOFF_BASE; exports.DEFAULT_RETRY_BACKOFF_MAX = DEFAULT_RETRY_BACKOFF_MAX; exports.DEFAULT_LOOP_HISTORY_PRUNE_INTERVAL = DEFAULT_LOOP_HISTORY_PRUNE_INTERVAL; exports.DEFAULT_STEP_TIMEOUT = DEFAULT_STEP_TIMEOUT; exports.WorkflowContextImpl = WorkflowContextImpl; exports.Loop = Loop; exports.runWorkflow = runWorkflow; exports.replayWorkflowFromStep = replayWorkflowFromStep;
3808
- //# sourceMappingURL=chunk-OYYWSC77.cjs.map
4180
+ //# sourceMappingURL=chunk-4SWXLWKL.cjs.map