or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-p-timeout

Timeout a promise after a specified amount of time

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/p-timeout@6.1.x

To install, run

npx @tessl/cli install tessl/npm-p-timeout@6.1.0

index.mddocs/

p-timeout

p-timeout provides a utility for adding timeout functionality to JavaScript promises, allowing developers to set time limits on asynchronous operations. It offers a simple API that wraps any promise and automatically rejects it with a TimeoutError if it doesn't resolve within the specified milliseconds.

Package Information

  • Package Name: p-timeout
  • Package Type: npm
  • Language: JavaScript (ES modules) with TypeScript definitions
  • Installation: npm install p-timeout

Core Imports

import pTimeout, { TimeoutError, AbortError } from 'p-timeout';

Individual imports:

import { TimeoutError, AbortError } from 'p-timeout';

Basic Usage

import { setTimeout } from 'node:timers/promises';
import pTimeout from 'p-timeout';

const delayedPromise = setTimeout(200);

// Timeout after 50ms - will throw TimeoutError
await pTimeout(delayedPromise, {
  milliseconds: 50,
});
//=> [TimeoutError: Promise timed out after 50 milliseconds]

Capabilities

Promise Timeout

Add timeout functionality to any promise with configurable error handling and cancellation support.

/**
 * Timeout a promise after a specified amount of time
 * @param input - Promise to decorate
 * @param options - Timeout configuration options
 * @returns A decorated promise that times out after specified milliseconds with a .clear() method
 */
function pTimeout<ValueType, ReturnType = ValueType>(
  input: PromiseLike<ValueType>,
  options: Options<ReturnType>
): ClearablePromise<ValueType | ReturnType>;

// Special overload for message: false case
function pTimeout<ValueType, ReturnType = ValueType>(
  input: PromiseLike<ValueType>,
  options: Options<ReturnType> & {message: false}
): ClearablePromise<ValueType | ReturnType | undefined>;

Usage Examples:

import pTimeout from 'p-timeout';
import { setTimeout } from 'node:timers/promises';

// Basic timeout
const result = await pTimeout(setTimeout(200, 'success'), {
  milliseconds: 100, // Will timeout
});

// Custom error message
try {
  await pTimeout(longRunningOperation(), {
    milliseconds: 5000,
    message: 'Operation took too long'
  });
} catch (error) {
  console.log(error.message); // 'Operation took too long'
}

// Silent timeout (resolves undefined instead of throwing)
const result = await pTimeout(slowPromise(), {
  milliseconds: 1000,
  message: false
});
// result will be undefined if timeout occurs

// Fallback function on timeout
const result = await pTimeout(unreliableAPI(), {
  milliseconds: 3000,
  fallback: () => 'default value'
});

// Clear timeout manually
const timeoutPromise = pTimeout(operation(), { milliseconds: 5000 });
// Later... cancel the timeout
timeoutPromise.clear();

AbortController Integration

Support for modern cancellation using AbortController signals.

// AbortController support through options.signal
interface Options<ReturnType> {
  signal?: AbortSignal;
  // ... other options
}

Usage Example:

import pTimeout from 'p-timeout';

const delayedPromise = new Promise(resolve => setTimeout(resolve, 3000));

const abortController = new AbortController();

// Cancel after 100ms
setTimeout(() => {
  abortController.abort();
}, 100);

await pTimeout(delayedPromise, {
  milliseconds: 2000,
  signal: abortController.signal
});
// Will throw AbortError or DOMException after 100ms

Error Classes

Custom error classes for different timeout and cancellation scenarios.

/**
 * Error thrown when a promise times out
 */
class TimeoutError extends Error {
  readonly name: 'TimeoutError';
  constructor(message?: string);
}

/**
 * Error thrown when request is aborted by AbortController 
 * (fallback when DOMException not available)
 */
class AbortError extends Error {
  readonly name: 'AbortError';
  constructor(message?: string);
}

Usage Example:

import pTimeout, { TimeoutError } from 'p-timeout';

try {
  await pTimeout(slowOperation(), { milliseconds: 1000 });
} catch (error) {
  if (error instanceof TimeoutError) {
    console.log('Operation timed out');
  }
}

// Custom error subclassing
class MyCustomError extends TimeoutError {
  name = "MyCustomError";
}

await pTimeout(operation(), {
  milliseconds: 5000,
  message: new MyCustomError('Custom timeout message')
});

Testing Support

Custom timer implementations for testing scenarios and fake timer compatibility.

interface Options<ReturnType> {
  customTimers?: {
    setTimeout: typeof globalThis.setTimeout;
    clearTimeout: typeof globalThis.clearTimeout;
  };
  // ... other options
}

Usage Example:

import pTimeout from 'p-timeout';
import sinon from 'sinon';

const originalSetTimeout = setTimeout;
const originalClearTimeout = clearTimeout;

sinon.useFakeTimers();

// Use pTimeout without being affected by sinon.useFakeTimers()
await pTimeout(doSomething(), {
  milliseconds: 2000,
  customTimers: {
    setTimeout: originalSetTimeout,
    clearTimeout: originalClearTimeout
  }
});

Cancelable Promise Support

Automatic integration with promises that have a .cancel() method.

// When input promise has .cancel() method, it will be called on timeout
// No special API required - works automatically

Usage Example:

import pTimeout from 'p-timeout';
import PCancelable from 'p-cancelable';

const cancelablePromise = new PCancelable((resolve, reject, onCancel) => {
  const timeoutId = setTimeout(resolve, 5000);
  onCancel(() => {
    clearTimeout(timeoutId);
    reject(new Error('Canceled'));
  });
});

// If timeout occurs, cancelablePromise.cancel() will be called automatically
await pTimeout(cancelablePromise, { milliseconds: 1000 });

Types

/**
 * Promise with additional clear() method to cancel timeout
 */
type ClearablePromise<T> = {
  clear: () => void;
} & Promise<T>;

/**
 * Configuration options for pTimeout function
 */
interface Options<ReturnType> {
  /** Milliseconds before timing out (required) */
  milliseconds: number;
  
  /** Custom error message, error to throw, or false to resolve undefined */
  message?: string | Error | false;
  
  /** Function to call on timeout instead of rejecting */
  fallback?: () => ReturnType | Promise<ReturnType>;
  
  /** Custom timer implementations for testing */
  readonly customTimers?: {
    setTimeout: typeof globalThis.setTimeout;
    clearTimeout: typeof globalThis.clearTimeout;
  };
  
  /** AbortController signal for cancellation */
  signal?: globalThis.AbortSignal;
}

Special Behaviors

  • Infinity milliseconds: Passing Infinity will cause it to never time out
  • Invalid milliseconds: Negative numbers or non-numbers throw TypeError
  • Pre-aborted signals: If signal is already aborted, promise rejects immediately
  • Environment compatibility: Uses DOMException when available, falls back to AbortError
  • Promise cancellation: Automatically calls .cancel() method on cancelable promises during timeout
  • Zero dependencies: Pure JavaScript with no runtime dependencies