Skip to main content

AbortSignal / Timeouts

BAML provides cancellation support for in-flight function calls across all language clients.

Language Support​

LanguageImplementationImport
TypeScriptAbortSignal APIBuilt-in (Node.js 15+)
PythonCustom AbortControllerfrom baml_py import AbortController
Gocontext.ContextBuilt-in
RubyNot supported-

Basic Usage​

// Manual cancellation
const controller = new AbortController()
const result = await b.FunctionName(input, {
signal: controller.signal
})

// Cancel operation
controller.abort()

// Automatic timeout
const result2 = await b.FunctionName(input, {
signal: AbortSignal.timeout(5000) // 5 second timeout
})

// Check if aborted
if (controller.signal.aborted) {
// Handle aborted state
}

AbortController Properties​

  • signal: AbortSignal - Read-only signal indicating if aborted

AbortController Methods​

  • abort(reason?: any): void - Cancels operation with optional reason

AbortSignal Static Methods​

  • AbortSignal.timeout(delay: number): AbortSignal - Auto-aborts after delay (ms)

Integration with Streaming​

const controller = new AbortController()
const stream = b.stream.FunctionName(input, {
signal: controller.signal
})

try {
for await (const chunk of stream) {
if (someCondition) {
controller.abort()
break
}
}
} catch (error) {
if (error instanceof BamlAbortError) {
console.log('Stream was aborted:', error.reason)
}
}

Error Types​

When an operation is aborted:

  • TypeScript: BamlAbortError
  • Python: BamlAbortError
  • Go: context.Canceled or context.DeadlineExceeded

Thread Safety​

note

Abort controllers are thread-safe and can be safely shared across multiple operations or threads.

Examples​

Basic Timeout​

// Modern approach
const result = await b.ExtractData(input, {
signal: AbortSignal.timeout(5000)
})

// Manual timeout
function withTimeout<T>(
operation: (signal: AbortSignal) => Promise<T>,
timeoutMs: number
): Promise<T> {
const controller = new AbortController()
const timeoutId = setTimeout(() => controller.abort(), timeoutMs)

return operation(controller.signal).finally(() => {
clearTimeout(timeoutId)
})
}

const result2 = await withTimeout(
(signal) => b.ExtractData(input, { signal }),
5000
)

Cancelling Multiple Operations​

const controller = new AbortController()

const operations = [
b.Operation1(input1, { signal: controller.signal }),
b.Operation2(input2, { signal: controller.signal }),
b.Operation3(input3, { signal: controller.signal })
]

try {
const results = await Promise.all(operations)
} catch (error) {
controller.abort() // Cancel remaining operations
throw error
}

See Also​