Skip to content

Commit 792787f

Browse files
authored
fix: Fix nightly and activity failing with non ApplicationFailure (#751)
1 parent 47b2133 commit 792787f

File tree

6 files changed

+52
-9
lines changed

6 files changed

+52
-9
lines changed

packages/common/src/failure.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -360,14 +360,15 @@ export function errorToFailure(err: unknown, payloadConverter: PayloadConverter)
360360
/**
361361
* If `err` is an Error it is turned into an `ApplicationFailure`.
362362
*
363-
* If `err` was already a `TemporalFailure`, returns the original error.
363+
* If `err` was already a `ApplicationFailure`, returns the original error.
364364
*
365365
* Otherwise returns an `ApplicationFailure` with `String(err)` as the message.
366366
*/
367-
export function ensureTemporalFailure(err: unknown): TemporalFailure {
368-
if (err instanceof TemporalFailure) {
367+
export function ensureApplicationFailure(err: unknown): ApplicationFailure {
368+
if (err instanceof ApplicationFailure) {
369369
return err;
370-
} else if (err instanceof Error) {
370+
}
371+
if (err instanceof Error) {
371372
const name = err.constructor?.name ?? err.name;
372373
const failure = new ApplicationFailure(err.message, name, false);
373374
failure.stack = err.stack;
@@ -379,6 +380,20 @@ export function ensureTemporalFailure(err: unknown): TemporalFailure {
379380
}
380381
}
381382

383+
/**
384+
* If `err` is an Error it is turned into an `ApplicationFailure`.
385+
*
386+
* If `err` was already a `TemporalFailure`, returns the original error.
387+
*
388+
* Otherwise returns an `ApplicationFailure` with `String(err)` as the message.
389+
*/
390+
export function ensureTemporalFailure(err: unknown): TemporalFailure {
391+
if (err instanceof TemporalFailure) {
392+
return err;
393+
}
394+
return ensureApplicationFailure(err);
395+
}
396+
382397
/**
383398
* Converts a Failure proto message to a JS Error object if defined or returns undefined.
384399
*/

packages/test/src/load/args.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ export interface WorkerArgSpec extends Spec {
6262
'--server-address': typeof String;
6363
'--otel-url': typeof String;
6464
'--status-port': typeof Number;
65+
'--shutdown-grace-time-ms': typeof String;
6566
}
6667

6768
export const workerArgSpec: WorkerArgSpec = {
@@ -77,6 +78,7 @@ export const workerArgSpec: WorkerArgSpec = {
7778
'--server-address': String,
7879
'--otel-url': String,
7980
'--status-port': Number,
81+
'--shutdown-grace-time-ms': String,
8082
};
8183

8284
export interface WrapperArgSpec extends Spec {

packages/test/src/load/worker.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ async function main() {
107107
const namespace = getRequired(args, '--ns');
108108
const taskQueue = getRequired(args, '--task-queue');
109109
const statusPort = args['--status-port'];
110+
const shutdownGraceTime = args['--shutdown-grace-time'] || '30s';
110111

111112
const telemetryOptions: TelemetryOptions = {
112113
tracingFilter: `temporal_sdk_core=${logLevel}`,
@@ -149,6 +150,7 @@ async function main() {
149150
maxConcurrentLocalActivityExecutions,
150151
maxConcurrentWorkflowTaskExecutions,
151152
maxCachedWorkflows,
153+
shutdownGraceTime,
152154
interceptors: {
153155
activityInbound: [() => new ConnectionInjectorInterceptor(clientConnection)],
154156
},

packages/test/src/test-worker-activities.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* eslint-disable @typescript-eslint/no-non-null-assertion */
22
import * as activity from '@temporalio/activity';
3-
import { defaultPayloadConverter, toPayloads } from '@temporalio/common';
3+
import { TemporalFailure, defaultPayloadConverter, toPayloads } from '@temporalio/common';
44
import { coresdk } from '@temporalio/proto';
55
import anyTest, { ExecutionContext, TestInterface } from 'ava';
66
import dedent from 'dedent';
@@ -253,3 +253,27 @@ test('Worker cancels activities after shutdown', async (t) => {
253253
t.truthy(result?.failed);
254254
t.true(activityCancelled);
255255
});
256+
257+
test('Non ApplicationFailure TemporalFailures thrown from Activity are wrapped with ApplicationFailure', async (t) => {
258+
const worker = isolateFreeWorker({
259+
...defaultOptions,
260+
activities: {
261+
async throwTemporalFailure() {
262+
throw new TemporalFailure('I should be valid');
263+
},
264+
},
265+
});
266+
t.context.worker = worker;
267+
268+
await runWorker(t, async () => {
269+
const taskToken = Buffer.from(uuid4());
270+
const { result } = await worker.native.runActivityTask({
271+
taskToken,
272+
start: {
273+
activityType: 'throwTemporalFailure',
274+
input: toPayloads(defaultPayloadConverter),
275+
},
276+
});
277+
t.is(result?.failed?.failure?.applicationFailureInfo?.type, 'TemporalFailure');
278+
});
279+
});

packages/worker/src/activity.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { asyncLocalStorage, Context, Info } from '@temporalio/activity';
22
import {
33
ApplicationFailure,
44
CancelledFailure,
5-
ensureTemporalFailure,
5+
ensureApplicationFailure,
66
FAILURE_SOURCE,
77
LoadedDataConverter,
88
} from '@temporalio/common';
@@ -96,7 +96,7 @@ export class Activity {
9696
}
9797
return {
9898
failed: {
99-
failure: await encodeErrorToFailure(this.dataConverter, ensureTemporalFailure(err)),
99+
failure: await encodeErrorToFailure(this.dataConverter, ensureApplicationFailure(err)),
100100
},
101101
};
102102
}

packages/worker/src/worker-options.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ export interface WorkerOptions {
9393
* Time to wait for pending tasks to drain after shutdown was requested.
9494
*
9595
* @format {@link https://www.npmjs.com/package/ms | ms} formatted string or number of milliseconds
96-
* @default 5s
96+
* @default 10s
9797
*/
9898
shutdownGraceTime?: string | number;
9999

@@ -323,7 +323,7 @@ export function addDefaultWorkerOptions(options: WorkerOptions): WorkerOptionsWi
323323
return {
324324
namespace: 'default',
325325
identity: `${process.pid}@${os.hostname()}`,
326-
shutdownGraceTime: '5s',
326+
shutdownGraceTime: '10s',
327327
maxConcurrentActivityTaskExecutions: 100,
328328
maxConcurrentLocalActivityExecutions: 100,
329329
enableNonLocalActivities: true,

0 commit comments

Comments
 (0)