Overview
functionTiming And Cancellation

runWithTimeout

Runs one behavior execution with a timeout.

Signature

tsSignature
export function runWithTimeout<I, O, E, C extends object>(
source: Behavior<I, O, E, C>,
input: I,
context: RuntimeContext<C>,
timeoutMs: number,
): Promise<Result<O, E | TimingError | Thrown>>;

Imports

tsImport
import { runWithTimeout } from "@/lib/flow/timeout";
import { runWithTimeout } from "@/lib/flow";

Type Parameters

I

Source input type.

O

Source output type.

E

Source domain error type.

C

Custom context type.

Parameters

source
Behavior<I, O, E, C>

Behavior to execute.

input
I

Input passed to the behavior.

context

Runtime context for this execution.

timeoutMs
number

Timeout in milliseconds.

Returns

A result containing source output, source domain error, timing error, or thrown error.

Return type
Promise<Result<O, E | TimingError | Thrown>>

Details

This advanced helper powers `timeout` and is exported for custom helper authors that need direct

control over input and context.

Behavior

Executable Flow workflow unit.

type
input

Creates an identity behavior for starting typed pipelines.

function
Result

Explicit success-or-failure outcome used throughout Flow.

type
Thrown

Runtime error returned when user code throws.

type

Source

tsflow/timeout.ts:69-116
export function runWithTimeout<I, O, E, C extends object>(
source: Behavior<I, O, E, C>,
input: I,
context: RuntimeContext<C>,
timeoutMs: number,
): Promise<Result<O, E | TimingError | Thrown>> {
if (context.signal.aborted) {
return Promise.resolve(resultFromSignal(context.signal));
}
const { controller, unlink } = createLinkedController(context.signal);
const childContext = contextWithSignal(context, controller.signal);
return new Promise((resolve) => {
let settled = false;
const settle = (result: Result<O, E | TimingError | Thrown>) => {
if (settled) {
return;
}
settled = true;
clearTimeout(timer);
context.signal.removeEventListener("abort", onAbort);
unlink();
resolve(result);
};
const onAbort = () => {
abortController(controller, context.signal.reason);
settle(resultFromSignal(context.signal));
};
const timer = setTimeout(
() => {
settle(err({ kind: "timeout" }));
abortController(controller, { kind: "timeout" });
},
Math.max(0, timeoutMs),
);
context.signal.addEventListener("abort", onAbort, { once: true });
runBehavior(source, input, childContext)
.then(settle)
.catch((error: unknown) => settle(thrown(error)));
});
}