Skip to content

Commit 9491a16

Browse files
authored
v3: Support decorators (#1060)
* Adds support for `emitDecoratorMetadata: true` and `experimentalDecorators: true` in your tsconfig * Implement task.onSuccess/onFailure and config.onSuccess/onFailure * Added onStart and more docs for lifecycle functions * Use onStart instead of init for TypeORM
1 parent 0a5aa2d commit 9491a16

File tree

19 files changed

+946
-34
lines changed

19 files changed

+946
-34
lines changed

.changeset/clever-carrots-travel.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@trigger.dev/sdk": patch
3+
"trigger.dev": patch
4+
"@trigger.dev/core": patch
5+
---
6+
7+
Implement task.onSuccess/onFailure and config.onSuccess/onFailure

.changeset/mighty-flowers-train.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
---
2+
"trigger.dev": patch
3+
"@trigger.dev/core": patch
4+
---
5+
6+
Adds support for `emitDecoratorMetadata: true` and `experimentalDecorators: true` in your tsconfig using the [`@anatine/esbuild-decorators`](https://github.com/anatine/esbuildnx/tree/main/packages/esbuild-decorators) package. This allows you to use libraries like TypeORM:
7+
8+
```ts orm/index.ts
9+
import "reflect-metadata";
10+
import { DataSource } from "typeorm";
11+
import { Entity, Column, PrimaryColumn } from "typeorm";
12+
13+
@Entity()
14+
export class Photo {
15+
@PrimaryColumn()
16+
id!: number;
17+
18+
@Column()
19+
name!: string;
20+
21+
@Column()
22+
description!: string;
23+
24+
@Column()
25+
filename!: string;
26+
27+
@Column()
28+
views!: number;
29+
30+
@Column()
31+
isPublished!: boolean;
32+
}
33+
34+
export const AppDataSource = new DataSource({
35+
type: "postgres",
36+
host: "localhost",
37+
port: 5432,
38+
username: "postgres",
39+
password: "postgres",
40+
database: "v3-catalog",
41+
entities: [Photo],
42+
synchronize: true,
43+
logging: false,
44+
});
45+
```
46+
47+
And then in your trigger.config.ts file you can initialize the datasource using the new `init` option:
48+
49+
```ts trigger.config.ts
50+
import type { TriggerConfig } from "@trigger.dev/sdk/v3";
51+
import { AppDataSource } from "@/trigger/orm";
52+
53+
export const config: TriggerConfig = {
54+
// ... other options here
55+
init: async (payload, { ctx }) => {
56+
await AppDataSource.initialize();
57+
},
58+
};
59+
```
60+
61+
Now you are ready to use this in your tasks:
62+
63+
```ts
64+
import { task } from "@trigger.dev/sdk/v3";
65+
import { AppDataSource, Photo } from "./orm";
66+
67+
export const taskThatUsesDecorators = task({
68+
id: "taskThatUsesDecorators",
69+
run: async (payload: { message: string }) => {
70+
console.log("Creating a photo...");
71+
72+
const photo = new Photo();
73+
photo.id = 2;
74+
photo.name = "Me and Bears";
75+
photo.description = "I am near polar bears";
76+
photo.filename = "photo-with-bears.jpg";
77+
photo.views = 1;
78+
photo.isPublished = true;
79+
80+
await AppDataSource.manager.save(photo);
81+
},
82+
});
83+
```

docs/v3/tasks-overview.mdx

Lines changed: 126 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ export const taskWithRetries = task({
7979
maxTimeoutInMs: 30_000,
8080
randomize: false,
8181
},
82-
run: async ({ payload, ctx }) => {
82+
run: async (payload: any, { ctx }) => {
8383
//...
8484
},
8585
});
@@ -99,7 +99,7 @@ export const oneAtATime = task({
9999
queue: {
100100
concurrencyLimit: 1,
101101
},
102-
run: async ({ payload, ctx }) => {
102+
run: async (payload: any, { ctx }) => {
103103
//...
104104
},
105105
});
@@ -116,35 +116,151 @@ export const heavyTask = task({
116116
cpu: 2,
117117
memory: 4,
118118
},
119-
run: async ({ payload, ctx }) => {
119+
run: async (payload: any, { ctx }) => {
120120
//...
121121
},
122122
});
123123
```
124124

125125
### `init` function
126126

127-
This function is called before a run attempt.
127+
This function is called before a run attempt:
128+
129+
```ts /trigger/init.ts
130+
export const taskWithInit = task({
131+
id: "task-with-init",
132+
init: async (payload, { ctx }) => {
133+
//...
134+
},
135+
run: async (payload: any, { ctx }) => {
136+
//...
137+
},
138+
});
139+
```
140+
141+
You can also return data from the `init` function that will be available in the params of the `run`, `cleanup`, `onSuccess`, and `onFailure` functions.
142+
143+
```ts /trigger/init-return.ts
144+
export const taskWithInitReturn = task({
145+
id: "task-with-init-return",
146+
init: async (payload, { ctx }) => {
147+
return { someData: "someValue" };
148+
},
149+
run: async (payload: any, { ctx, init }) => {
150+
console.log(init.someData); // "someValue"
151+
},
152+
});
153+
```
128154

129155
### `cleanup` function
130156

131-
This function is called after a run attempt has succeeded or failed.
157+
This function is called after the `run` function is executed, regardless of whether the run was successful or not. It's useful for cleaning up resources, logging, or other side effects.
158+
159+
```ts /trigger/cleanup.ts
160+
export const taskWithCleanup = task({
161+
id: "task-with-cleanup",
162+
cleanup: async (payload, { ctx }) => {
163+
//...
164+
},
165+
run: async (payload: any, { ctx }) => {
166+
//...
167+
},
168+
});
169+
```
132170

133171
### `middleware` function
134172

135173
This function is called before the `run` function, it allows you to wrap the run function with custom code. For more information [read the guide](/v3/middleware).
136174

175+
### `onStart` function
176+
177+
When a task run starts, the `onStart` function is called. It's useful for sending notifications, logging, and other side effects. This function will only be called one per run (not per retry). If you want to run code before each retry, use the `init` function.
178+
179+
```ts /trigger/on-start.ts
180+
export const taskWithOnStart = task({
181+
id: "task-with-on-start",
182+
onStart: async (payload, { ctx }) => {
183+
//...
184+
},
185+
run: async (payload: any, { ctx }) => {
186+
//...
187+
},
188+
});
189+
```
190+
191+
You can also define an `onStart` function in your `trigger.config.ts` file to get notified when any task starts.
192+
193+
```ts trigger.config.ts
194+
import type { TriggerConfig } from "@trigger.dev/sdk/v3";
195+
196+
export const config: TriggerConfig = {
197+
onStart: async (payload, { ctx }) => {
198+
console.log("Task started", ctx.task.id);
199+
},
200+
};
201+
```
202+
137203
### `onSuccess` function
138204

139-
When a task attempt succeeds, the `onSuccess` function is called. It's useful for sending notifications, logging, or other side effects.
205+
When a task run succeeds, the `onSuccess` function is called. It's useful for sending notifications, logging, syncing state to your database, or other side effects.
140206

141-
<Snippet file="coming-soon-slim.mdx" />
207+
```ts /trigger/on-success.ts
208+
export const taskWithOnSuccess = task({
209+
id: "task-with-on-success",
210+
onSuccess: async (payload, output, { ctx }) => {
211+
//...
212+
},
213+
run: async (payload: any, { ctx }) => {
214+
//...
215+
},
216+
});
217+
```
218+
219+
You can also define an `onSuccess` function in your `trigger.config.ts` file to get notified when any task succeeds.
220+
221+
```ts trigger.config.ts
222+
import type { TriggerConfig } from "@trigger.dev/sdk/v3";
223+
224+
export const config: TriggerConfig = {
225+
onSuccess: async (payload, output, { ctx }) => {
226+
console.log("Task succeeded", ctx.task.id);
227+
},
228+
};
229+
```
230+
231+
### `onFailure` function
232+
233+
When a task run fails, the `onFailure` function is called. It's useful for sending notifications, logging, or other side effects. It will only be executed once the task run has exhausted all its retries.
234+
235+
```ts /trigger/on-failure.ts
236+
export const taskWithOnFailure = task({
237+
id: "task-with-on-failure",
238+
onFailure: async (payload, error, { ctx }) => {
239+
//...
240+
},
241+
run: async (payload: any, { ctx }) => {
242+
//...
243+
},
244+
});
245+
```
246+
247+
You can also define an `onFailure` function in your `trigger.config.ts` file to get notified when any task fails.
248+
249+
```ts trigger.config.ts
250+
import type { TriggerConfig } from "@trigger.dev/sdk/v3";
251+
252+
export const config: TriggerConfig = {
253+
onFailure: async (payload, error, { ctx }) => {
254+
console.log("Task failed", ctx.task.id);
255+
},
256+
};
257+
```
142258

143-
### `onError` function
259+
### `handleError` functions
144260

145-
When a task attempt fails, the `onError` function is called. It's useful for sending notifications, logging, or other side effects.
261+
You can define a function that will be called when an error is thrown in the `run` function, that allows you to control how the error is handled and whether the task should be retried.
146262

147-
<Snippet file="coming-soon-slim.mdx" />
263+
Read more about `handleError` in our [Errors and Retrying guide](/v3/errors-retrying).
148264

149265
## Next steps
150266

0 commit comments

Comments
 (0)