feat: pass args to task onSuccess and onFail callbacks (#13269)

### What?
Passes the same args provided to a task's `shouldRestore` function to
both the `onSuccess` & `onFail` callbacks

### Why?
Currently `onSuccess` and `onFail` are quite useless without any
context, this will allow for a wider range of functionality:

- Checking if it's the last failure
- Access to the task `input`
- Access to `req` to allow logging, email notifications, etc.

### How?
1. Created a new `TaskCallbackArgs` type, which replicates the args of
the `ShouldRestoreFn` type.
2. Add a `TaskCallbackFn` type
3. Update the function calls of both `onSuccess` and `onFail`.

### Questions
- I wasn't sure about the typing of `input` – I can see `input: input!`
being used elsewhere for task errors so I replicated that.
- Same for `taskStatus`, I added a type check but I'm not sure if this
is the right approach (what would scenario would result in a `null`
value?). Should `TaskCallbackArgs['taskStatus']` be typed to allow for
`null` values?

---------

Co-authored-by: Alessio Gravili <alessio@gravili.de>
This commit is contained in:
Slava Nossar
2025-09-16 11:37:09 +10:00
committed by GitHub
parent 9a841df38c
commit 3acdbf6b25
3 changed files with 24 additions and 9 deletions

View File

@@ -127,15 +127,20 @@ export type RunInlineTaskFunction = <TTaskInput extends object, TTaskOutput exte
},
) => Promise<TTaskOutput>
export type ShouldRestoreFn = (args: {
export type TaskCallbackArgs = {
/**
* Input data passed to the task
*/
input: object
input?: object
job: Job
req: PayloadRequest
taskStatus: SingleTaskStatus<string>
}) => boolean | Promise<boolean>
taskStatus: null | SingleTaskStatus<string>
}
export type ShouldRestoreFn = (
args: { taskStatus: SingleTaskStatus<string> } & Omit<TaskCallbackArgs, 'taskStatus'>,
) => boolean | Promise<boolean>
export type TaskCallbackFn = (args: TaskCallbackArgs) => Promise<void> | void
export type RetryConfig = {
/**
@@ -220,11 +225,11 @@ export type TaskConfig<
/**
* Function to be executed if the task fails.
*/
onFail?: () => Promise<void> | void
onFail?: TaskCallbackFn
/**
* Function to be executed if the task succeeds.
*/
onSuccess?: () => Promise<void> | void
onSuccess?: TaskCallbackFn
/**
* Define the output field schema - payload will generate a type for this schema.
*/

View File

@@ -47,7 +47,12 @@ export async function handleTaskError({
} = error.args
if (taskConfig?.onFail) {
await taskConfig.onFail()
await taskConfig.onFail({
input,
job,
req,
taskStatus,
})
}
const errorJSON = {

View File

@@ -95,7 +95,7 @@ export const getRunTaskFunction = <TIsInline extends boolean>(
shouldRestore = false
} else if (typeof finalRetriesConfig?.shouldRestore === 'function') {
shouldRestore = await finalRetriesConfig.shouldRestore({
input: input!,
input,
job,
req,
taskStatus,
@@ -182,7 +182,12 @@ export const getRunTaskFunction = <TIsInline extends boolean>(
}
if (taskConfig?.onSuccess) {
await taskConfig.onSuccess()
await taskConfig.onSuccess({
input,
job,
req,
taskStatus,
})
}
const newLogItem: JobLog = {