alepha
Version:
Easy-to-use modern TypeScript framework for building many kind of applications.
51 lines (46 loc) • 1.55 kB
text/typescript
import { AlephaError, createMiddleware, type Middleware } from "alepha";
import {
DateTimeProvider,
type DurationLike,
} from "../providers/DateTimeProvider.ts";
/**
* Middleware that aborts handler execution if it exceeds a duration limit.
*
* Uses `Promise.race` with a managed timeout from `DateTimeProvider` —
* if the handler doesn't resolve before the deadline, the promise rejects.
* Uses managed timeouts so it works with `DateTimeProvider.travel()` in tests.
*
* ```typescript
* class OrderService {
* processOrder = $pipeline({
* use: [$timeout([30, "seconds"])],
* handler: async (orderId: string) => {
* return await this.orders.updateById(orderId, { status: "paid" });
* },
* });
* }
* ```
*/
export const $timeout = (duration: DurationLike): Middleware => {
return createMiddleware({
name: "$timeout",
options: { duration },
handler: ({ alepha, next }) => {
const dateTimeProvider = alepha.inject(DateTimeProvider);
return async (...args) => {
let rejectTimeout: (reason: Error) => void;
const timeoutPromise = new Promise<never>((_, reject) => {
rejectTimeout = reject;
});
const timer = dateTimeProvider.createTimeout(() => {
rejectTimeout(new AlephaError("$timeout: handler exceeded deadline"));
}, duration);
try {
return await Promise.race([next(...args), timeoutPromise]);
} finally {
dateTimeProvider.clearTimeout(timer);
}
};
},
});
};