Execute other tasks

Compose tasks together to create multi-step executions
Using the Airplane SDK, you can execute tasks programmatically from within other tasks. This is commonly used to execute code in other languages (e.g. executing a Shell task from a JavaScript task), to parallelize work, and to share logic between tasks.

Executing tasks with inline configuration

If your task is written in JavaScript or Python and you want to call a task that is written in the same language and that uses inline configuration, then you can call that task directly:
typescript
Copied
1
import airplane from "airplane";
2
3
export default airplane.task(
4
{
5
slug: "my_task",
6
},
7
async () => {
8
// This task will execute the child task defined in getUser.
9
const run = await getUser();
10
const user = run.output;
11
// ...
12
}
13
);
14
15
type User = { id: string; name: string; email: string };
16
17
export const getUser = airplane.task(
18
{
19
slug: "get_user",
20
},
21
async (): Promise<User> => {
22
const user = { id: "123", name: "Example", email: "example@airplane.dev" };
23
return user;
24
}
25
);

Executing tasks by slug

You can execute a task inside another task by referring to its slug. To execute a task from another task, use the airplane.execute method from the JavaScript or Python SDK. To do so, you'll first need its task slug from the task editor. Pass this slug and an optional set of parameters into the SDK's execute method:
typescript
Copied
1
import airplane from "airplane";
2
3
type User = { id: string; name: string; email: string };
4
5
export default airplane.task(
6
{
7
slug: "my_task",
8
},
9
async () => {
10
const taskSlug = "CHILD_TASK_SLUG"; // Replace this with your task slug.
11
const run = await airplane.execute<User>(taskSlug, {
12
email: "colin@airplane.dev", // Replace this with your task's parameters.
13
});
14
return run.output;
15
}
16
);
Under the hood, this will look up the task's slug and perform a call to airplane.execute.
The airplane.execute method asynchronously returns a Run object with the following fields:
FieldDescription
idThe unique identifier of the run.
taskIDThe unique identifier of the executed task.
paramValuesAn object with the parameter values.
statusThe run's status. This will always be Succeeded. If a run was cancelled or failed, the SDK will throw an error that can be optionally caught. See Error handling below.
outputThe run's output. Defaults to null if the run produced no output.

Error handling

If a child task fails, a RunTerminationError will be thrown by airplane.execute. By default, this will bubble up and fail the parent task. You can handle these errors yourself by wrapping the task execution:
typescript
Copied
1
import airplane, { RunTerminationError } from "airplane";
2
3
export default airplane.task(
4
{
5
slug: "javascript_example",
6
},
7
async () => {
8
const taskSlug = "CHILD_TASK_SLUG"; // Replace this with your task slug.
9
10
try {
11
const run = await airplane.execute<User>(taskSlug, {
12
email: "colin@airplane.dev", // Replace this with your task's parameters.
13
});
14
return run.output;
15
} catch (err) {
16
if (!(err instanceof RunTerminationError)) {
17
throw err;
18
}
19
console.log(`This task failed with status=${err.run.status}`);
20
}
21
}
22
);
23
24
type User = { id: string; name: string; email: string };

Execute rules & constraints

  • Tasks are limited to 10 concurrent child runs and 1000 total child runs.
  • All child runs are subject to the constraints of their parent. If the parent run times out or is cancelled, any child tasks that are in progress will be timed out or cancelled.