AbortSignal / Timeouts

Overview

BAML provides cancellation support for in-flight function calls across all language clients. In TypeScript, this uses the modern AbortSignal API, while other languages use their native patterns.

Language Support

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

API Reference

TypeScript

// Manual cancellation
const controller = new AbortController()
const result = await b.FunctionName(input, {
signal: controller.signal
})
// Cancel operation
controller.abort()
// Automatic timeout using AbortSignal.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 that indicates if the controller has been aborted

AbortController Methods

  • abort(reason?: any): void - Cancels the associated operation(s) with an optional reason

AbortSignal Static Methods

  • AbortSignal.timeout(delay: number): AbortSignal - Creates a signal that automatically aborts after the specified delay in milliseconds

Integration with Streaming

Abort controllers work seamlessly with streaming responses:

const controller = new AbortController()
const stream = b.stream.FunctionName(input, {
signal: controller.signal
})
try {
for await (const chunk of stream) {
// Process chunk
if (someCondition) {
controller.abort() // Stops the stream
break
}
}
} catch (error) {
if (error instanceof BamlAbortError) {
console.log('Stream was aborted:', error.reason)
}
}

Error Types

When an operation is aborted, language-specific errors are thrown:

  • TypeScript: BamlAbortError
  • Python: BamlAbortError
  • Go: context.Canceled or context.DeadlineExceeded
  • Rust: Error containing “cancel” or “timeout” in debug representation
  • Ruby: Not supported

See BamlAbortError for detailed error handling information.

Thread Safety

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

The Node.js AbortController is thread-safe by design.

Examples

Basic Timeout Implementation

// Modern approach using AbortSignal.timeout()
const result = await b.ExtractData(input, {
signal: AbortSignal.timeout(5000) // 5 second timeout
})
// Manual timeout implementation
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)
})
}
// Usage
const result2 = await withTimeout(
(signal) => b.ExtractData(input, { signal }),
5000 // 5 second timeout
)

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 })
]
// Cancel all if any fails
try {
const results = await Promise.all(operations)
} catch (error) {
controller.abort() // Cancel remaining operations
throw error
}