@temporalio/common 1.3.0 → 1.4.1

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.
Files changed (116) hide show
  1. package/lib/activity-options.d.ts +138 -0
  2. package/lib/activity-options.js +15 -0
  3. package/lib/activity-options.js.map +1 -0
  4. package/lib/converter/data-converter.d.ts +20 -1
  5. package/lib/converter/data-converter.js +14 -3
  6. package/lib/converter/data-converter.js.map +1 -1
  7. package/lib/converter/failure-converter.d.ts +75 -0
  8. package/lib/converter/failure-converter.js +239 -0
  9. package/lib/converter/failure-converter.js.map +1 -0
  10. package/lib/converter/payload-codec.d.ts +1 -1
  11. package/lib/converter/payload-converter.d.ts +85 -1
  12. package/lib/converter/payload-converter.js +210 -1
  13. package/lib/converter/payload-converter.js.map +1 -1
  14. package/lib/converter/protobuf-payload-converters.d.ts +3 -3
  15. package/lib/converter/protobuf-payload-converters.js +20 -19
  16. package/lib/converter/protobuf-payload-converters.js.map +1 -1
  17. package/lib/converter/types.d.ts +0 -6
  18. package/lib/converter/types.js +7 -18
  19. package/lib/converter/types.js.map +1 -1
  20. package/lib/deprecated-time.d.ts +52 -0
  21. package/lib/deprecated-time.js +106 -0
  22. package/lib/deprecated-time.js.map +1 -0
  23. package/lib/{converter/encoding.d.ts → encoding.d.ts} +8 -0
  24. package/lib/{converter/encoding.js → encoding.js} +15 -1
  25. package/lib/encoding.js.map +1 -0
  26. package/lib/errors.d.ts +47 -0
  27. package/lib/errors.js +68 -0
  28. package/lib/errors.js.map +1 -0
  29. package/lib/failure.d.ts +0 -27
  30. package/lib/failure.js +9 -205
  31. package/lib/failure.js.map +1 -1
  32. package/lib/index.d.ts +39 -8
  33. package/lib/index.js +64 -7
  34. package/lib/index.js.map +1 -1
  35. package/lib/interceptors.d.ts +18 -0
  36. package/lib/interceptors.js +24 -0
  37. package/lib/interceptors.js.map +1 -0
  38. package/lib/interfaces.d.ts +52 -0
  39. package/lib/interfaces.js +3 -0
  40. package/lib/interfaces.js.map +1 -0
  41. package/lib/internal-non-workflow/codec-helpers.d.ts +82 -0
  42. package/lib/internal-non-workflow/codec-helpers.js +295 -0
  43. package/lib/internal-non-workflow/codec-helpers.js.map +1 -0
  44. package/lib/internal-non-workflow/codec-types.d.ts +22 -0
  45. package/lib/internal-non-workflow/codec-types.js +3 -0
  46. package/lib/internal-non-workflow/codec-types.js.map +1 -0
  47. package/lib/internal-non-workflow/data-converter-helpers.d.ts +11 -0
  48. package/lib/internal-non-workflow/data-converter-helpers.js +66 -0
  49. package/lib/internal-non-workflow/data-converter-helpers.js.map +1 -0
  50. package/lib/internal-non-workflow/index.d.ts +10 -0
  51. package/lib/internal-non-workflow/index.js +27 -0
  52. package/lib/internal-non-workflow/index.js.map +1 -0
  53. package/lib/internal-non-workflow/tls-config.d.ts +32 -0
  54. package/lib/internal-non-workflow/tls-config.js +11 -0
  55. package/lib/internal-non-workflow/tls-config.js.map +1 -0
  56. package/lib/internal-non-workflow/utils.d.ts +4 -0
  57. package/lib/internal-non-workflow/utils.js +11 -0
  58. package/lib/internal-non-workflow/utils.js.map +1 -0
  59. package/lib/otel.d.ts +1 -1
  60. package/lib/otel.js +2 -2
  61. package/lib/otel.js.map +1 -1
  62. package/lib/retry-policy.d.ts +48 -0
  63. package/lib/retry-policy.js +62 -0
  64. package/lib/retry-policy.js.map +1 -0
  65. package/lib/time.d.ts +18 -0
  66. package/lib/time.js +79 -0
  67. package/lib/time.js.map +1 -0
  68. package/lib/type-helpers.d.ts +21 -0
  69. package/lib/type-helpers.js +46 -0
  70. package/lib/type-helpers.js.map +1 -0
  71. package/lib/workflow-handle.d.ts +27 -0
  72. package/lib/workflow-handle.js +3 -0
  73. package/lib/workflow-handle.js.map +1 -0
  74. package/lib/workflow-options.d.ts +118 -0
  75. package/lib/workflow-options.js +53 -0
  76. package/lib/workflow-options.js.map +1 -0
  77. package/package.json +5 -4
  78. package/src/activity-options.ts +159 -0
  79. package/src/converter/data-converter.ts +24 -3
  80. package/src/converter/failure-converter.ts +355 -0
  81. package/src/converter/payload-codec.ts +1 -1
  82. package/src/converter/payload-converter.ts +246 -1
  83. package/src/converter/protobuf-payload-converters.ts +14 -25
  84. package/src/converter/types.ts +6 -19
  85. package/src/deprecated-time.ts +80 -0
  86. package/src/{converter/encoding.ts → encoding.ts} +14 -0
  87. package/src/errors.ts +55 -0
  88. package/src/failure.ts +1 -251
  89. package/src/index.ts +55 -8
  90. package/src/interceptors.ts +32 -0
  91. package/src/interfaces.ts +64 -0
  92. package/src/internal-non-workflow/codec-helpers.ts +348 -0
  93. package/src/internal-non-workflow/codec-types.ts +34 -0
  94. package/src/internal-non-workflow/data-converter-helpers.ts +81 -0
  95. package/src/internal-non-workflow/index.ts +10 -0
  96. package/src/internal-non-workflow/tls-config.ts +35 -0
  97. package/src/internal-non-workflow/utils.ts +6 -0
  98. package/src/otel.ts +2 -2
  99. package/src/retry-policy.ts +101 -0
  100. package/src/time.ts +79 -0
  101. package/src/type-helpers.ts +64 -0
  102. package/src/workflow-handle.ts +30 -0
  103. package/src/workflow-options.ts +156 -0
  104. package/lib/converter/encoding.js.map +0 -1
  105. package/lib/converter/json-payload-converter.d.ts +0 -10
  106. package/lib/converter/json-payload-converter.js +0 -39
  107. package/lib/converter/json-payload-converter.js.map +0 -1
  108. package/lib/converter/payload-converters.d.ts +0 -67
  109. package/lib/converter/payload-converters.js +0 -124
  110. package/lib/converter/payload-converters.js.map +0 -1
  111. package/lib/converter/search-attribute-payload-converter.d.ts +0 -12
  112. package/lib/converter/search-attribute-payload-converter.js +0 -64
  113. package/lib/converter/search-attribute-payload-converter.js.map +0 -1
  114. package/src/converter/json-payload-converter.ts +0 -37
  115. package/src/converter/payload-converters.ts +0 -148
  116. package/src/converter/search-attribute-payload-converter.ts +0 -71
@@ -0,0 +1,159 @@
1
+ import type { coresdk } from '@temporalio/proto';
2
+ import { RetryPolicy } from './retry-policy';
3
+ import { checkExtends } from './type-helpers';
4
+
5
+ // Avoid importing the proto implementation to reduce workflow bundle size
6
+ // Copied from coresdk.workflow_commands.ActivityCancellationType
7
+ export enum ActivityCancellationType {
8
+ TRY_CANCEL = 0,
9
+ WAIT_CANCELLATION_COMPLETED = 1,
10
+ ABANDON = 2,
11
+ }
12
+
13
+ checkExtends<coresdk.workflow_commands.ActivityCancellationType, ActivityCancellationType>();
14
+ checkExtends<ActivityCancellationType, coresdk.workflow_commands.ActivityCancellationType>();
15
+
16
+ /**
17
+ * Options for remote activity invocation
18
+ */
19
+ export interface ActivityOptions {
20
+ /**
21
+ * Identifier to use for tracking the activity in Workflow history.
22
+ * The `activityId` can be accessed by the activity function.
23
+ * Does not need to be unique.
24
+ *
25
+ * @default an incremental sequence number
26
+ */
27
+ activityId?: string;
28
+
29
+ /**
30
+ * Task queue name.
31
+ *
32
+ * @default current worker task queue
33
+ */
34
+ taskQueue?: string;
35
+
36
+ /**
37
+ * Heartbeat interval. Activity must heartbeat before this interval passes after a last heartbeat or activity start.
38
+ * @format number of milliseconds or {@link https://www.npmjs.com/package/ms | ms-formatted string}
39
+ */
40
+ heartbeatTimeout?: string | number;
41
+
42
+ /**
43
+ * RetryPolicy that define how activity is retried in case of failure. If this is not set, then the server-defined default activity retry policy will be used. To ensure zero retries, set maximum attempts to 1.
44
+ */
45
+ retry?: RetryPolicy;
46
+
47
+ /**
48
+ * Maximum time of a single Activity execution attempt.
49
+ Note that the Temporal Server doesn't detect Worker process failures directly. It relies on this timeout to detect that an Activity that didn't complete on time. So this timeout should be as short as the longest possible execution of the Activity body. Potentially long running Activities must specify {@link heartbeatTimeout} and call {@link activity.Context.heartbeat} periodically for timely failure detection.
50
+
51
+ * Either this option or {@link scheduleToCloseTimeout} is required.
52
+ * @format number of milliseconds or {@link https://www.npmjs.com/package/ms | ms-formatted string}
53
+ */
54
+ startToCloseTimeout?: string | number;
55
+ /**
56
+ * Time that the Activity Task can stay in the Task Queue before it is picked up by a Worker. Do not specify this timeout unless using host specific Task Queues for Activity Tasks are being used for routing.
57
+ * `scheduleToStartTimeout` is always non-retryable. Retrying after this timeout doesn't make sense as it would just put the Activity Task back into the same Task Queue.
58
+ * @default unlimited
59
+ * @format number of milliseconds or {@link https://www.npmjs.com/package/ms | ms-formatted string}
60
+ */
61
+ scheduleToStartTimeout?: string | number;
62
+
63
+ /**
64
+ * Total time that a workflow is willing to wait for Activity to complete.
65
+ * `scheduleToCloseTimeout` limits the total time of an Activity's execution including retries (use {@link startToCloseTimeout} to limit the time of a single attempt).
66
+ *
67
+ * Either this option or {@link startToCloseTimeout} is required
68
+ * @default unlimited
69
+ * @format number of milliseconds or {@link https://www.npmjs.com/package/ms | ms-formatted string}
70
+ */
71
+ scheduleToCloseTimeout?: string | number;
72
+
73
+ /**
74
+ * Determines what the SDK does when the Activity is cancelled.
75
+ * - `TRY_CANCEL` - Initiate a cancellation request and immediately report cancellation to the workflow.
76
+ * - `WAIT_CANCELLATION_COMPLETED` - Wait for activity cancellation completion. Note that activity must heartbeat to receive a
77
+ * cancellation notification. This can block the cancellation for a long time if activity doesn't
78
+ * heartbeat or chooses to ignore the cancellation request.
79
+ * - `ABANDON` - Do not request cancellation of the activity and immediately report cancellation to the workflow.
80
+ */
81
+ cancellationType?: ActivityCancellationType;
82
+
83
+ /**
84
+ * Eager dispatch is an optimization that improves the throughput and load on the server for scheduling Activities.
85
+ * When used, the server will hand out Activity tasks back to the Worker when it completes a Workflow task.
86
+ * It is available from server version 1.17 behind the `system.enableActivityEagerExecution` feature flag.
87
+ *
88
+ * Eager dispatch will only be used if `allowEagerDispatch` is enabled (the default) and {@link taskQueue} is either
89
+ * omitted or the same as the current Workflow.
90
+ *
91
+ * @default true
92
+ */
93
+ allowEagerDispatch?: boolean;
94
+ }
95
+
96
+ /**
97
+ * Options for local activity invocation
98
+ */
99
+ export interface LocalActivityOptions {
100
+ /**
101
+ * RetryPolicy that defines how an activity is retried in case of failure. If this is not set, then the SDK-defined default activity retry policy will be used.
102
+ * Note that local activities are always executed at least once, even if maximum attempts is set to 1 due to Workflow task retries.
103
+ */
104
+ retry?: RetryPolicy;
105
+
106
+ /**
107
+ * Maximum time the local activity is allowed to execute after the task is dispatched. This
108
+ * timeout is always retryable.
109
+ *
110
+ * Either this option or {@link scheduleToCloseTimeout} is required.
111
+ * If set, this must be <= {@link scheduleToCloseTimeout}, otherwise, it will be clamped down.
112
+ *
113
+ * @format number of milliseconds or {@link https://www.npmjs.com/package/ms | ms-formatted string}
114
+ */
115
+ startToCloseTimeout?: string | number;
116
+
117
+ /**
118
+ * Limits time the local activity can idle internally before being executed. That can happen if
119
+ * the worker is currently at max concurrent local activity executions. This timeout is always
120
+ * non retryable as all a retry would achieve is to put it back into the same queue. Defaults
121
+ * to {@link scheduleToCloseTimeout} if not specified and that is set. Must be <=
122
+ * {@link scheduleToCloseTimeout} when set, otherwise, it will be clamped down.
123
+ *
124
+ * @default unlimited
125
+ * @format number of milliseconds or {@link https://www.npmjs.com/package/ms | ms-formatted string}
126
+ */
127
+ scheduleToStartTimeout?: string | number;
128
+
129
+ /**
130
+ * Indicates how long the caller is willing to wait for local activity completion. Limits how
131
+ * long retries will be attempted. When not specified defaults to the workflow execution
132
+ * timeout (which may be unset).
133
+ *
134
+ * Either this option or {@link startToCloseTimeout} is required.
135
+ *
136
+ * @default unlimited
137
+ * @format number of milliseconds or {@link https://www.npmjs.com/package/ms | ms-formatted string}
138
+ */
139
+ scheduleToCloseTimeout?: string | number;
140
+
141
+ /**
142
+ * If the activity is retrying and backoff would exceed this value, a server side timer will be scheduled for the next attempt.
143
+ * Otherwise, backoff will happen internally in the SDK.
144
+ *
145
+ * @default 1 minute
146
+ * @format number of milliseconds or {@link https://www.npmjs.com/package/ms | ms-formatted string}
147
+ **/
148
+ localRetryThreshold?: string | number;
149
+
150
+ /**
151
+ * Determines what the SDK does when the Activity is cancelled.
152
+ * - `TRY_CANCEL` - Initiate a cancellation request and immediately report cancellation to the workflow.
153
+ * - `WAIT_CANCELLATION_COMPLETED` - Wait for activity cancellation completion. Note that activity must heartbeat to receive a
154
+ * cancellation notification. This can block the cancellation for a long time if activity doesn't
155
+ * heartbeat or chooses to ignore the cancellation request.
156
+ * - `ABANDON` - Do not request cancellation of the activity and immediately report cancellation to the workflow.
157
+ */
158
+ cancellationType?: coresdk.workflow_commands.ActivityCancellationType;
159
+ }
@@ -1,6 +1,6 @@
1
+ import { DefaultFailureConverter, FailureConverter } from './failure-converter';
1
2
  import { PayloadCodec } from './payload-codec';
2
- import { PayloadConverter } from './payload-converter';
3
- import { defaultPayloadConverter } from './payload-converters';
3
+ import { defaultPayloadConverter, PayloadConverter } from './payload-converter';
4
4
 
5
5
  /**
6
6
  * When your data (arguments and return values) is sent over the wire and stored by Temporal Server, it is encoded in
@@ -29,11 +29,20 @@ import { defaultPayloadConverter } from './payload-converters';
29
29
  export interface DataConverter {
30
30
  /**
31
31
  * Path of a file that has a `payloadConverter` named export.
32
- * `payloadConverter` should be an instance of a class that implements {@link PayloadConverter}.
32
+ * `payloadConverter` should be an object that implements {@link PayloadConverter}.
33
33
  * If no path is provided, {@link defaultPayloadConverter} is used.
34
34
  */
35
35
  payloadConverterPath?: string;
36
36
 
37
+ /**
38
+ * Path of a file that has a `failureConverter` named export.
39
+ * `failureConverter` should be an object that implements {@link FailureConverter}.
40
+ * If no path is provided, {@link defaultFailureConverter} is used.
41
+ *
42
+ * @experimental
43
+ */
44
+ failureConverterPath?: string;
45
+
37
46
  /**
38
47
  * An array of {@link PayloadCodec} instances.
39
48
  *
@@ -49,10 +58,22 @@ export interface DataConverter {
49
58
  */
50
59
  export interface LoadedDataConverter {
51
60
  payloadConverter: PayloadConverter;
61
+ failureConverter: FailureConverter;
52
62
  payloadCodecs: PayloadCodec[];
53
63
  }
54
64
 
65
+ /**
66
+ * The default {@link FailureConverter} used by the SDK.
67
+ *
68
+ * Error messages and stack traces are serizalized as plain text.
69
+ */
70
+ export const defaultFailureConverter: FailureConverter = new DefaultFailureConverter();
71
+
72
+ /**
73
+ * A "loaded" data converter that uses the default set of failure and payload converters.
74
+ */
55
75
  export const defaultDataConverter: LoadedDataConverter = {
56
76
  payloadConverter: defaultPayloadConverter,
77
+ failureConverter: defaultFailureConverter,
57
78
  payloadCodecs: [],
58
79
  };
@@ -0,0 +1,355 @@
1
+ import {
2
+ ActivityFailure,
3
+ ApplicationFailure,
4
+ CancelledFailure,
5
+ ChildWorkflowFailure,
6
+ FAILURE_SOURCE,
7
+ ProtoFailure,
8
+ RetryState,
9
+ ServerFailure,
10
+ TemporalFailure,
11
+ TerminatedFailure,
12
+ TimeoutFailure,
13
+ TimeoutType,
14
+ } from '../failure';
15
+ import { hasOwnProperties, isRecord } from '../type-helpers';
16
+ import {
17
+ arrayFromPayloads,
18
+ defaultPayloadConverter,
19
+ fromPayloadsAtIndex,
20
+ PayloadConverter,
21
+ toPayloads,
22
+ } from './payload-converter';
23
+
24
+ /**
25
+ * Stack traces will be cutoff when on of these patterns is matched
26
+ */
27
+ const CUTOFF_STACK_PATTERNS = [
28
+ /** Activity execution */
29
+ /\s+at Activity\.execute \(.*[\\/]worker[\\/](?:src|lib)[\\/]activity\.[jt]s:\d+:\d+\)/,
30
+ /** Workflow activation */
31
+ /\s+at Activator\.\S+NextHandler \(.*[\\/]workflow[\\/](?:src|lib)[\\/]internals\.[jt]s:\d+:\d+\)/,
32
+ /** Workflow run anything in context */
33
+ /\s+at Script\.runInContext \((?:node:vm|vm\.js):\d+:\d+\)/,
34
+ ];
35
+
36
+ /**
37
+ * Cuts out the framework part of a stack trace, leaving only user code entries
38
+ */
39
+ export function cutoffStackTrace(stack?: string): string {
40
+ const lines = (stack ?? '').split(/\r?\n/);
41
+ const acc = Array<string>();
42
+ lineLoop: for (const line of lines) {
43
+ for (const pattern of CUTOFF_STACK_PATTERNS) {
44
+ if (pattern.test(line)) break lineLoop;
45
+ }
46
+ acc.push(line);
47
+ }
48
+ return acc.join('\n');
49
+ }
50
+
51
+ /**
52
+ * A `FailureConverter` is responsible to convert from proto `Failure` instances to JS `Errors` and back.
53
+ *
54
+ * It is recommended to use the {@link DefaultFailureConverter} and not attempt to customize the default implementation
55
+ * in order to maintain cross language failure serialization compatibility.
56
+ *
57
+ * @experimental
58
+ */
59
+ export interface FailureConverter {
60
+ /**
61
+ * Converts a caught error to a Failure proto message.
62
+ */
63
+ errorToFailure(err: unknown): ProtoFailure;
64
+ /**
65
+ * Converts a Failure proto message to a JS Error object.
66
+ */
67
+ failureToError(err: ProtoFailure): TemporalFailure;
68
+ }
69
+
70
+ /**
71
+ * The "shape" of the attributes set as the {@link ProtoFailure.encodedAttributes} payload in case
72
+ * {@link DefaultEncodedFailureAttributes.encodeCommonAttributes} is set to `true`.
73
+ */
74
+ export interface DefaultEncodedFailureAttributes {
75
+ message: string;
76
+ stack_trace: string;
77
+ }
78
+
79
+ /**
80
+ * Options for the {@link DefaultFailureConverter} constructor.
81
+ */
82
+ export interface DefaultFailureConverterOptions {
83
+ /**
84
+ * The {@link PayloadConverter} to use for converting failure attributes.
85
+ */
86
+ payloadConverter: PayloadConverter;
87
+ /**
88
+ * Whether to encode error messages and stack traces (for encrypting these attributes use a {@link PayloadCodec}).
89
+ */
90
+ encodeCommonAttributes: boolean;
91
+ }
92
+
93
+ /**
94
+ * Default cross language compatible failure converter.
95
+ *
96
+ * By default, it will leave error messages and stack traces as plain text. In order to encrypt those, set
97
+ * `encodeCommonAttributes` to `true` in the constructor options and make sure to use a {@link PayloadCodec} that can
98
+ * encrypt / decrypt payloads in your Worker and Client options.
99
+ *
100
+ * @experimental
101
+ */
102
+ export class DefaultFailureConverter implements FailureConverter {
103
+ public readonly options: DefaultFailureConverterOptions;
104
+
105
+ constructor(options?: Partial<DefaultFailureConverterOptions>) {
106
+ const { encodeCommonAttributes, payloadConverter } = options ?? {};
107
+ this.options = {
108
+ encodeCommonAttributes: encodeCommonAttributes ?? false,
109
+ payloadConverter: payloadConverter ?? defaultPayloadConverter,
110
+ };
111
+ }
112
+
113
+ /**
114
+ * Converts a Failure proto message to a JS Error object.
115
+ *
116
+ * Does not set common properties, that is done in {@link failureToError}.
117
+ */
118
+ failureToErrorInner(failure: ProtoFailure): TemporalFailure {
119
+ if (failure.applicationFailureInfo) {
120
+ return new ApplicationFailure(
121
+ failure.message ?? undefined,
122
+ failure.applicationFailureInfo.type,
123
+ Boolean(failure.applicationFailureInfo.nonRetryable),
124
+ arrayFromPayloads(this.options.payloadConverter, failure.applicationFailureInfo.details?.payloads),
125
+ this.optionalFailureToOptionalError(failure.cause)
126
+ );
127
+ }
128
+ if (failure.serverFailureInfo) {
129
+ return new ServerFailure(
130
+ failure.message ?? undefined,
131
+ Boolean(failure.serverFailureInfo.nonRetryable),
132
+ this.optionalFailureToOptionalError(failure.cause)
133
+ );
134
+ }
135
+ if (failure.timeoutFailureInfo) {
136
+ return new TimeoutFailure(
137
+ failure.message ?? undefined,
138
+ fromPayloadsAtIndex(
139
+ this.options.payloadConverter,
140
+ 0,
141
+ failure.timeoutFailureInfo.lastHeartbeatDetails?.payloads
142
+ ),
143
+ failure.timeoutFailureInfo.timeoutType ?? TimeoutType.TIMEOUT_TYPE_UNSPECIFIED
144
+ );
145
+ }
146
+ if (failure.terminatedFailureInfo) {
147
+ return new TerminatedFailure(failure.message ?? undefined, this.optionalFailureToOptionalError(failure.cause));
148
+ }
149
+ if (failure.canceledFailureInfo) {
150
+ return new CancelledFailure(
151
+ failure.message ?? undefined,
152
+ arrayFromPayloads(this.options.payloadConverter, failure.canceledFailureInfo.details?.payloads),
153
+ this.optionalFailureToOptionalError(failure.cause)
154
+ );
155
+ }
156
+ if (failure.resetWorkflowFailureInfo) {
157
+ return new ApplicationFailure(
158
+ failure.message ?? undefined,
159
+ 'ResetWorkflow',
160
+ false,
161
+ arrayFromPayloads(
162
+ this.options.payloadConverter,
163
+ failure.resetWorkflowFailureInfo.lastHeartbeatDetails?.payloads
164
+ ),
165
+ this.optionalFailureToOptionalError(failure.cause)
166
+ );
167
+ }
168
+ if (failure.childWorkflowExecutionFailureInfo) {
169
+ const { namespace, workflowType, workflowExecution, retryState } = failure.childWorkflowExecutionFailureInfo;
170
+ if (!(workflowType?.name && workflowExecution)) {
171
+ throw new TypeError('Missing attributes on childWorkflowExecutionFailureInfo');
172
+ }
173
+ return new ChildWorkflowFailure(
174
+ namespace ?? undefined,
175
+ workflowExecution,
176
+ workflowType.name,
177
+ retryState ?? RetryState.RETRY_STATE_UNSPECIFIED,
178
+ this.optionalFailureToOptionalError(failure.cause)
179
+ );
180
+ }
181
+ if (failure.activityFailureInfo) {
182
+ if (!failure.activityFailureInfo.activityType?.name) {
183
+ throw new TypeError('Missing activityType?.name on activityFailureInfo');
184
+ }
185
+ return new ActivityFailure(
186
+ failure.activityFailureInfo.activityType.name,
187
+ failure.activityFailureInfo.activityId ?? undefined,
188
+ failure.activityFailureInfo.retryState ?? RetryState.RETRY_STATE_UNSPECIFIED,
189
+ failure.activityFailureInfo.identity ?? undefined,
190
+ this.optionalFailureToOptionalError(failure.cause)
191
+ );
192
+ }
193
+ return new TemporalFailure(failure.message ?? undefined, this.optionalFailureToOptionalError(failure.cause));
194
+ }
195
+
196
+ failureToError(failure: ProtoFailure): TemporalFailure {
197
+ if (failure.encodedAttributes) {
198
+ const attrs = this.options.payloadConverter.fromPayload<DefaultEncodedFailureAttributes>(
199
+ failure.encodedAttributes
200
+ );
201
+ // Don't apply encodedAttributes unless they conform to an expected schema
202
+ if (typeof attrs === 'object' && attrs !== null) {
203
+ const { message, stack_trace } = attrs;
204
+ // Avoid mutating the argument
205
+ failure = { ...failure };
206
+ if (typeof message === 'string') {
207
+ failure.message = message;
208
+ }
209
+ if (typeof stack_trace === 'string') {
210
+ failure.stackTrace = stack_trace;
211
+ }
212
+ }
213
+ }
214
+ const err = this.failureToErrorInner(failure);
215
+ err.stack = failure.stackTrace ?? '';
216
+ err.failure = failure;
217
+ return err;
218
+ }
219
+
220
+ errorToFailure(err: unknown): ProtoFailure {
221
+ const failure = this.errorToFailureInner(err);
222
+ if (this.options.encodeCommonAttributes) {
223
+ const { message, stackTrace } = failure;
224
+ failure.message = 'Encoded failure';
225
+ failure.stackTrace = '';
226
+ failure.encodedAttributes = this.options.payloadConverter.toPayload({ message, stack_trace: stackTrace });
227
+ }
228
+ return failure;
229
+ }
230
+
231
+ errorToFailureInner(err: unknown): ProtoFailure {
232
+ if (err instanceof TemporalFailure) {
233
+ if (err.failure) return err.failure;
234
+ const base = {
235
+ message: err.message,
236
+ stackTrace: cutoffStackTrace(err.stack),
237
+ cause: this.optionalErrorToOptionalFailure(err.cause),
238
+ source: FAILURE_SOURCE,
239
+ };
240
+
241
+ if (err instanceof ActivityFailure) {
242
+ return {
243
+ ...base,
244
+ activityFailureInfo: {
245
+ ...err,
246
+ activityType: { name: err.activityType },
247
+ },
248
+ };
249
+ }
250
+ if (err instanceof ChildWorkflowFailure) {
251
+ return {
252
+ ...base,
253
+ childWorkflowExecutionFailureInfo: {
254
+ ...err,
255
+ workflowExecution: err.execution,
256
+ workflowType: { name: err.workflowType },
257
+ },
258
+ };
259
+ }
260
+ if (err instanceof ApplicationFailure) {
261
+ return {
262
+ ...base,
263
+ applicationFailureInfo: {
264
+ type: err.type,
265
+ nonRetryable: err.nonRetryable,
266
+ details:
267
+ err.details && err.details.length
268
+ ? { payloads: toPayloads(this.options.payloadConverter, ...err.details) }
269
+ : undefined,
270
+ },
271
+ };
272
+ }
273
+ if (err instanceof CancelledFailure) {
274
+ return {
275
+ ...base,
276
+ canceledFailureInfo: {
277
+ details:
278
+ err.details && err.details.length
279
+ ? { payloads: toPayloads(this.options.payloadConverter, ...err.details) }
280
+ : undefined,
281
+ },
282
+ };
283
+ }
284
+ if (err instanceof TimeoutFailure) {
285
+ return {
286
+ ...base,
287
+ timeoutFailureInfo: {
288
+ timeoutType: err.timeoutType,
289
+ lastHeartbeatDetails: err.lastHeartbeatDetails
290
+ ? { payloads: toPayloads(this.options.payloadConverter, err.lastHeartbeatDetails) }
291
+ : undefined,
292
+ },
293
+ };
294
+ }
295
+ if (err instanceof TerminatedFailure) {
296
+ return {
297
+ ...base,
298
+ terminatedFailureInfo: {},
299
+ };
300
+ }
301
+ if (err instanceof ServerFailure) {
302
+ return {
303
+ ...base,
304
+ serverFailureInfo: { nonRetryable: err.nonRetryable },
305
+ };
306
+ }
307
+ // Just a TemporalFailure
308
+ return base;
309
+ }
310
+
311
+ const base = {
312
+ source: FAILURE_SOURCE,
313
+ };
314
+
315
+ if (isRecord(err) && hasOwnProperties(err, ['message', 'stack'])) {
316
+ return {
317
+ ...base,
318
+ message: String(err.message) ?? '',
319
+ stackTrace: cutoffStackTrace(String(err.stack)),
320
+ cause: this.optionalErrorToOptionalFailure(err.cause),
321
+ };
322
+ }
323
+
324
+ const recommendation = ` [A non-Error value was thrown from your code. We recommend throwing Error objects so that we can provide a stack trace]`;
325
+
326
+ if (typeof err === 'string') {
327
+ return { ...base, message: err + recommendation };
328
+ }
329
+ if (typeof err === 'object') {
330
+ let message = '';
331
+ try {
332
+ message = JSON.stringify(err);
333
+ } catch (_err) {
334
+ message = String(err);
335
+ }
336
+ return { ...base, message: message + recommendation };
337
+ }
338
+
339
+ return { ...base, message: String(err) + recommendation };
340
+ }
341
+
342
+ /**
343
+ * Converts a Failure proto message to a JS Error object if defined or returns undefined.
344
+ */
345
+ optionalFailureToOptionalError(failure: ProtoFailure | undefined | null): TemporalFailure | undefined {
346
+ return failure ? this.failureToError(failure) : undefined;
347
+ }
348
+
349
+ /**
350
+ * Converts an error to a Failure proto message if defined or returns undefined
351
+ */
352
+ optionalErrorToOptionalFailure(err: unknown): ProtoFailure | undefined {
353
+ return err ? this.errorToFailure(err) : undefined;
354
+ }
355
+ }
@@ -1,4 +1,4 @@
1
- import { Payload } from './types';
1
+ import { Payload } from '../interfaces';
2
2
 
3
3
  /**
4
4
  * `PayloadCodec` is an optional step that happens between the wire and the {@link PayloadConverter}: