Skip to content

timeout

Races the pipeline against a configurable deadline. On timeout, sets the response status and detail via closure, then destroys the request stream. The timer is cleared automatically when the response finishes.

Pipeline stage: Cross-cutting

import {timeout} from '@centralping/ergo';
Option Type Default Description
ms number 30_000 (30s) Timeout duration in milliseconds — must be a positive finite number at most 2_147_483_647 (Node setTimeout max)
statusCode 408 | 504 408 HTTP status on timeout — must be 408 or 504

Construction throws TypeError when ms or statusCode fail these checks.

The middleware is side-effect only — it does not produce a domain accumulator value. On timeout it sets responseAcc.statusCode and responseAcc.detail directly.

Status Condition
408 Request Timeout Default — deadline exceeded
504 Gateway Timeout When configured with statusCode: 504

The error detail is: Request timed out after ${ms}ms.

import {compose, timeout} from '@centralping/ergo';
const pipeline = compose(
timeout({ms: 10_000, statusCode: 504}),
async (req, res, acc) => ({
response: {body: await slowOperation(), statusCode: 200},
}),
);

In ergo-router, timeout participates in Config Resolution — set a global default in defaults and override or disable it per route:

import createRouter from '@centralping/ergo-router';
const router = createRouter({
defaults: {
timeout: {ms: 5_000},
},
});
// Inherits the 5s default
router.get('/users', {
execute: async (req, res, acc) => ({
response: {body: await listUsers()},
}),
});
// Override: 30s for a slow report
router.get('/reports/quarterly', {
timeout: {ms: 30_000},
execute: async (req, res, acc) => ({
response: {body: await generateQuarterlyReport()},
}),
});
// Disable: SSE connections are long-lived
router.get('/events', {
timeout: false,
noSend: true,
execute: sseHandler,
});

See the auto-generated timeout API docs.