From 0d05ff317c34f874df6f5cffa16bc042b6741629 Mon Sep 17 00:00:00 2001 From: Alessio Gravili Date: Tue, 28 Apr 2026 12:09:12 -0700 Subject: [PATCH 1/2] commit --- .../src/queues/config/types/taskTypes.ts | 45 ++++------------ .../runJobs/runJob/getRunTaskFunction.ts | 52 ++++++------------- 2 files changed, 27 insertions(+), 70 deletions(-) diff --git a/packages/payload/src/queues/config/types/taskTypes.ts b/packages/payload/src/queues/config/types/taskTypes.ts index ee526e7e334..2538d4b013b 100644 --- a/packages/payload/src/queues/config/types/taskTypes.ts +++ b/packages/payload/src/queues/config/types/taskTypes.ts @@ -15,25 +15,13 @@ export type TaskInputOutput = { } export type TaskHandlerResult< TTaskSlugOrInputOutput extends keyof TypedJobs['tasks'] | TaskInputOutput, -> = - | { - /** - * @deprecated Returning `state: 'failed'` is deprecated. Throw an error instead. - */ - errorMessage?: string - /** - * @deprecated Returning `state: 'failed'` is deprecated. Throw an error instead. - */ - state: 'failed' - } - | { - output: TTaskSlugOrInputOutput extends keyof TypedJobs['tasks'] - ? TypedJobs['tasks'][TTaskSlugOrInputOutput]['output'] - : TTaskSlugOrInputOutput extends TaskInputOutput // Check if it's actually TaskInputOutput type - ? TTaskSlugOrInputOutput['output'] - : never - state?: 'succeeded' - } +> = { + output: TTaskSlugOrInputOutput extends keyof TypedJobs['tasks'] + ? TypedJobs['tasks'][TTaskSlugOrInputOutput]['output'] + : TTaskSlugOrInputOutput extends TaskInputOutput // Check if it's actually TaskInputOutput type + ? TTaskSlugOrInputOutput['output'] + : never +} export type TaskHandlerArgs< TTaskSlugOrInputOutput extends keyof TypedJobs['tasks'] | TaskInputOutput, @@ -125,22 +113,9 @@ export type RunInlineTaskFunction = req: PayloadRequest tasks: RunTaskFunctions - }) => MaybePromise< - | { - /** - * @deprecated Returning `state: 'failed'` is deprecated. Throw an error instead. - */ - errorMessage?: string - /** - * @deprecated Returning `state: 'failed'` is deprecated. Throw an error instead. - */ - state: 'failed' - } - | { - output: TTaskOutput - state?: 'succeeded' - } - > + }) => MaybePromise<{ + output: TTaskOutput + }> }, ) => Promise diff --git a/packages/payload/src/queues/operations/runJobs/runJob/getRunTaskFunction.ts b/packages/payload/src/queues/operations/runJobs/runJob/getRunTaskFunction.ts index bb55e4d4e84..a3b56212d8e 100644 --- a/packages/payload/src/queues/operations/runJobs/runJob/getRunTaskFunction.ts +++ b/packages/payload/src/queues/operations/runJobs/runJob/getRunTaskFunction.ts @@ -1,7 +1,7 @@ import ObjectIdImport from 'bson-objectid' import type { Job } from '../../../../index.js' -import type { JsonObject, PayloadRequest } from '../../../../types/index.js' +import type { PayloadRequest } from '../../../../types/index.js' import type { RetryConfig, RunInlineTaskFunction, @@ -128,23 +128,24 @@ export const getRunTaskFunction = ( }) } - let taskHandlerResult: TaskHandlerResult - let output: JsonObject | undefined = {} + let output: TaskHandlerResult['output'] try { - taskHandlerResult = await runner({ - inlineTask: getRunTaskFunction(job, workflowConfig, req, true, updateJob, { - taskID, - taskSlug, - }), - input, - job: job as unknown as Job, - req, - tasks: getRunTaskFunction(job, workflowConfig, req, false, updateJob, { - taskID, - taskSlug, - }), - }) + output = ( + await runner({ + inlineTask: getRunTaskFunction(job, workflowConfig, req, true, updateJob, { + taskID, + taskSlug, + }), + input, + job: job as unknown as Job, + req, + tasks: getRunTaskFunction(job, workflowConfig, req, false, updateJob, { + taskID, + taskSlug, + }), + }) + )?.output } catch (err: any) { if (err instanceof JobCancelledError) { // Re-throw JobCancelledError to be handled by the top-level error handler @@ -166,25 +167,6 @@ export const getRunTaskFunction = ( }) } - if (taskHandlerResult.state === 'failed') { - throw new TaskError({ - executedAt, - input: input!, - job, - message: taskHandlerResult.errorMessage ?? 'Task handler returned a failed state', - output, - parent, - retriesConfig: finalRetriesConfig, - taskConfig, - taskID, - taskSlug, - taskStatus, - workflowConfig, - }) - } else { - output = taskHandlerResult.output - } - if (taskConfig?.onSuccess) { await taskConfig.onSuccess({ input, From bb5bff8b56b2815efba5c6f7cc538354493e6160 Mon Sep 17 00:00:00 2001 From: Alessio Gravili Date: Tue, 28 Apr 2026 12:24:57 -0700 Subject: [PATCH 2/2] test changes --- test/queues/getConfig.ts | 4 -- test/queues/int.spec.ts | 46 +--------------------- test/queues/payload-types.ts | 29 ++------------ test/queues/runners/updatePost.ts | 12 +----- test/queues/tasks/DoNothingTask.ts | 1 - test/queues/tasks/ReturnCustomErrorTask.ts | 20 ---------- test/queues/tasks/ReturnErrorTask.ts | 13 ------ 7 files changed, 6 insertions(+), 119 deletions(-) delete mode 100644 test/queues/tasks/ReturnCustomErrorTask.ts delete mode 100644 test/queues/tasks/ReturnErrorTask.ts diff --git a/test/queues/getConfig.ts b/test/queues/getConfig.ts index 8d5115514b8..8044533e66c 100644 --- a/test/queues/getConfig.ts +++ b/test/queues/getConfig.ts @@ -12,8 +12,6 @@ import { CreateSimpleTask } from './tasks/CreateSimpleTask.js' import { CreateSimpleWithDuplicateMessageTask } from './tasks/CreateSimpleWithDuplicateMessageTask.js' import { DoNothingTask } from './tasks/DoNothingTask.js' import { ExternalTask } from './tasks/ExternalTask.js' -import { ReturnCustomErrorTask } from './tasks/ReturnCustomErrorTask.js' -import { ReturnErrorTask } from './tasks/ReturnErrorTask.js' import { SelfCancelTask } from './tasks/SelfCancelTask.js' import { ThrowErrorTask } from './tasks/ThrowErrorTask.js' import { UpdatePostStep2Task } from './tasks/UpdatePostStep2Task.js' @@ -148,8 +146,6 @@ export const getConfig: () => Partial = () => ({ CreateSimpleWithDuplicateMessageTask, ExternalTask, ThrowErrorTask, - ReturnErrorTask, - ReturnCustomErrorTask, DoNothingTask, SelfCancelTask, ], diff --git a/test/queues/int.spec.ts b/test/queues/int.spec.ts index f69da1639b6..a53a3e67da3 100644 --- a/test/queues/int.spec.ts +++ b/test/queues/int.spec.ts @@ -14,8 +14,8 @@ import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it } from import type { NextRESTClient } from '../__helpers/shared/NextRESTClient.js' -import { devUser } from '../credentials.js' import { initPayloadInt } from '../__helpers/shared/initPayloadInt.js' +import { devUser } from '../credentials.js' import { clearAndSeedEverything } from './seed.js' import { waitUntilAutorunIsDone } from './utilities.js' @@ -1770,50 +1770,6 @@ describe('Queues - Payload', () => { expect(jobAfterRun?.log?.[0]?.state).toBe('failed') }) - it('can tasks return error', async () => { - payload.config.jobs.deleteJobOnComplete = false - - const job = await payload.jobs.queue({ - task: 'ReturnError', - input: {}, - }) - - await payload.jobs.run({ silent: true }) - - const jobAfterRun = await payload.findByID({ - collection: 'payload-jobs', - id: job.id, - }) - - expect(jobAfterRun.hasError).toBe(true) - expect(jobAfterRun.log?.length).toBe(1) - expect(jobAfterRun?.log?.[0]?.error?.message).toBe('Task handler returned a failed state') - expect(jobAfterRun?.log?.[0]?.state).toBe('failed') - }) - - it('can tasks return error with custom error message', async () => { - payload.config.jobs.deleteJobOnComplete = false - - const job = await payload.jobs.queue({ - task: 'ReturnCustomError', - input: { - errorMessage: 'custom error message', - }, - }) - - await payload.jobs.run({ silent: true }) - - const jobAfterRun = await payload.findByID({ - collection: 'payload-jobs', - id: job.id, - }) - - expect(jobAfterRun.hasError).toBe(true) - expect(jobAfterRun.log?.length).toBe(1) - expect(jobAfterRun?.log?.[0]?.error?.message).toBe('custom error message') - expect(jobAfterRun?.log?.[0]?.state).toBe('failed') - }) - it('can reliably run workflows with parallel tasks', async () => { if (process.env.PAYLOAD_DATABASE === 'supabase') { // TODO: This test is flaky on supabase in CI, so we skip it for now diff --git a/test/queues/payload-types.ts b/test/queues/payload-types.ts index 5b2c814a0b6..e9f8b8c5a34 100644 --- a/test/queues/payload-types.ts +++ b/test/queues/payload-types.ts @@ -105,8 +105,6 @@ export interface Config { CreateSimpleWithDuplicateMessage: TaskCreateSimpleWithDuplicateMessage; ExternalTask: TaskExternalTask; ThrowError: TaskThrowError; - ReturnError: TaskReturnError; - ReturnCustomError: TaskReturnCustomError; DoNothingTask: TaskDoNothingTask; SelfCancel: TaskSelfCancel; inline: { @@ -302,8 +300,6 @@ export interface PayloadJob { | 'CreateSimpleWithDuplicateMessage' | 'ExternalTask' | 'ThrowError' - | 'ReturnError' - | 'ReturnCustomError' | 'DoNothingTask' | 'SelfCancel'; taskID: string; @@ -378,8 +374,6 @@ export interface PayloadJob { | 'CreateSimpleWithDuplicateMessage' | 'ExternalTask' | 'ThrowError' - | 'ReturnError' - | 'ReturnCustomError' | 'DoNothingTask' | 'SelfCancel' ) @@ -667,24 +661,7 @@ export interface TaskThrowError { input?: unknown; output?: unknown; } -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "TaskReturnError". - */ -export interface TaskReturnError { - input?: unknown; - output?: unknown; -} -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "TaskReturnCustomError". - */ -export interface TaskReturnCustomError { - input: { - errorMessage: string; - }; - output?: unknown; -} + /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "TaskDoNothingTask". @@ -942,6 +919,6 @@ export interface Auth { declare module 'payload' { - // @ts-ignore + // @ts-ignore export interface GeneratedTypes extends Config {} -} \ No newline at end of file +} diff --git a/test/queues/runners/updatePost.ts b/test/queues/runners/updatePost.ts index b09caf3956c..ebcca1b31d0 100644 --- a/test/queues/runners/updatePost.ts +++ b/test/queues/runners/updatePost.ts @@ -5,10 +5,7 @@ export const updatePostStep1: TaskHandler<'UpdatePost'> = async ({ req, input }) typeof input.post === 'string' || typeof input.post === 'number' ? input.post : input.post.id if (!postID) { - return { - state: 'failed', - output: null, - } + throw new Error('No post ID provided') } await req.payload.update({ @@ -21,7 +18,6 @@ export const updatePostStep1: TaskHandler<'UpdatePost'> = async ({ req, input }) }) return { - state: 'succeeded', output: { messageTwice: input.message + input.message, }, @@ -33,10 +29,7 @@ export const updatePostStep2: TaskHandler<'UpdatePostStep2'> = async ({ req, inp typeof input.post === 'string' || typeof input.post === 'number' ? input.post : input.post.id if (!postID) { - return { - state: 'failed', - output: null, - } + throw new Error('No post ID provided') } await req.payload.update({ @@ -49,7 +42,6 @@ export const updatePostStep2: TaskHandler<'UpdatePostStep2'> = async ({ req, inp }) return { - state: 'succeeded', output: null, } } diff --git a/test/queues/tasks/DoNothingTask.ts b/test/queues/tasks/DoNothingTask.ts index 4f9b018be71..ca9f58d10e2 100644 --- a/test/queues/tasks/DoNothingTask.ts +++ b/test/queues/tasks/DoNothingTask.ts @@ -14,7 +14,6 @@ export const DoNothingTask: TaskConfig<'DoNothingTask'> = { outputSchema: [], handler: async ({ input }) => { return { - state: 'succeeded', output: { message: input.message, }, diff --git a/test/queues/tasks/ReturnCustomErrorTask.ts b/test/queues/tasks/ReturnCustomErrorTask.ts deleted file mode 100644 index 0c7253d26fc..00000000000 --- a/test/queues/tasks/ReturnCustomErrorTask.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type { TaskConfig } from 'payload' - -export const ReturnCustomErrorTask: TaskConfig<'ReturnCustomError'> = { - retries: 0, - slug: 'ReturnCustomError', - inputSchema: [ - { - name: 'errorMessage', - type: 'text', - required: true, - }, - ], - outputSchema: [], - handler: ({ input }) => { - return { - state: 'failed', - errorMessage: input.errorMessage, - } - }, -} diff --git a/test/queues/tasks/ReturnErrorTask.ts b/test/queues/tasks/ReturnErrorTask.ts deleted file mode 100644 index 661551ddd42..00000000000 --- a/test/queues/tasks/ReturnErrorTask.ts +++ /dev/null @@ -1,13 +0,0 @@ -import type { TaskConfig } from 'payload' - -export const ReturnErrorTask: TaskConfig<'ReturnError'> = { - retries: 0, - slug: 'ReturnError', - inputSchema: [], - outputSchema: [], - handler: () => { - return { - state: 'failed', - } - }, -}