timeout
Wraps a promise with a timeout, rejecting if it doesn't resolve within the specified time. Creates a race between the provided promise and a timeout. If the promise doesn't resolve or reject before the timeout, it will be rejected with a timeout error. Useful for preventing indefinite hangs, enforcing SLAs, or handling slow operations gracefully.
Installation
npx fragmen add promise/timeoutSource Code
/**
* Wraps a promise with a timeout, rejecting if it doesn't resolve within the specified time.
*
* Creates a race between the provided promise and a timeout. If the promise doesn't resolve
* or reject before the timeout, it will be rejected with a timeout error. Useful for preventing
* indefinite hangs, enforcing SLAs, or handling slow operations gracefully.
*
* @param {Promise<T>} promise The promise to wrap with a timeout
* @param {number} ms The timeout in milliseconds
* @param {string} message Optional custom error message (default: "Operation timed out after {ms}ms")
* @returns {Promise<T>} A promise that resolves with the original promise's value or rejects on timeout
*
* @example
* ```typescript
* // Fetch with timeout
* const fetchData = fetch('https://api.example.com/data');
* const result = await timeout(fetchData, 5000);
* // Rejects if fetch takes longer than 5 seconds
*
* // Custom timeout message
* const slowOperation = someAsyncFunction();
* try {
* await timeout(slowOperation, 3000, 'API request took too long');
* } catch (error) {
* console.error(error.message); // 'API request took too long'
* }
*
* // With async/await
* async function loadData() {
* try {
* const data = await timeout(
* fetchDataFromServer(),
* 10000
* );
* return data;
* } catch (error) {
* console.error('Request timed out');
* return null;
* }
* }
* ```
*/
export function timeout<T>(
promise: Promise<T>,
ms: number,
message?: string
): Promise<T> {
// Validate inputs
if (!(promise instanceof Promise)) {
throw new TypeError('First argument must be a Promise');
}
if (typeof ms !== 'number' || ms < 0) {
throw new RangeError('Timeout must be a non-negative number');
}
// Create timeout promise
const timeoutPromise = new Promise<never>((_, reject) => {
setTimeout(() => {
const errorMessage = message ?? `Operation timed out after ${ms}ms`;
const error = new Error(errorMessage);
error.name = 'TimeoutError';
reject(error);
}, ms);
});
// Race between the original promise and timeout
return Promise.race([promise, timeoutPromise]);
}
Examples
// Fetch with timeout
const fetchData = fetch('https://api.example.com/data');
const result = await timeout(fetchData, 5000);
// Rejects if fetch takes longer than 5 seconds
// Custom timeout message
const slowOperation = someAsyncFunction();
try {
await timeout(slowOperation, 3000, 'API request took too long');
} catch (error) {
console.error(error.message); // 'API request took too long'
}
// With async/await
async function loadData() {
try {
const data = await timeout(
fetchDataFromServer(),
10000
);
return data;
} catch (error) {
console.error('Request timed out');
return null;
}
}
Related Utilities
all-settled-typed
promiseType-safe Promise.allSettled with separated results
delay
promiseReturns a promise that resolves after a given number of milliseconds. Creates an artificial delay using Promise and setTimeout. Useful for implementing timeouts, rate limiting, animation delays, or simulating async operations in testing.
retry
promiseRetries a promise-returning function a specified number of times with exponential backoff. Attempts to execute the function, and if it fails, retries up to the specified number of times. Each retry waits longer than the previous one (exponential backoff). Useful for handling flaky network requests, rate-limited APIs, or temporary failures.
Quick Actions
Parameters
promisePromise<T>The promise to wrap with a timeout
msnumberThe timeout in milliseconds
messagestringOptional custom error message (default: "Operation timed out after {ms}ms")
Returns
Promise<T>A promise that resolves with the original promise's value or rejects on timeout