UNPKG

@daiso-tech/core

Version:

The library offers flexible, framework-agnostic solutions for modern web applications, built on adaptable components that integrate seamlessly with popular frameworks like Next Js.

151 lines 4.8 kB
/** * @module Resilience */ import {} from "../../../execution-context/contracts/execution-context.contract.js"; import {} from "../../../middleware/contracts/_module.js"; import { RetryIntervalResilienceError } from "../../../resilience/implementations/resilience.errors.js"; import { handleOnExecutionAttempt, handleOnRetryDelay, } from "../../../resilience/implementations/retry/_module.js"; import {} from "../../../time-span/contracts/_module.js"; import { TimeSpan } from "../../../time-span/implementations/_module.js"; import { callErrorPolicyOnThrow, callErrorPolicyOnValue, delay, UnexpectedError, } from "../../../utilities/_module.js"; /** * @internal */ async function handleWhenReturn(settings) { const { onExecutionAttempt, attempt, args, context, next, errorPolicy, intervalAsTimeSpan, endDate, onRetryDelay, allErrors, } = settings; handleOnExecutionAttempt({ onExecutionAttempt, attempt, args, context, }); const value = await next(); if (!callErrorPolicyOnValue(errorPolicy, value)) { return { type: "return", value, }; } // Handle retrying if an false is returned allErrors.push(value); handleOnRetryDelay({ onRetryDelay, error: value, waitTime: intervalAsTimeSpan, attempt, args, context, }); const remainingAfterValue = endDate.getTime() - Date.now(); if (remainingAfterValue <= 0) { return { type: "break", }; } await delay(intervalAsTimeSpan); return { type: "end", }; } /** * @internal */ async function handleWhenThrow(settings) { const { allErrors, error, errorPolicy, onRetryDelay, intervalAsTimeSpan, attempt, args, context, endDate, } = settings; if (await callErrorPolicyOnThrow(errorPolicy, error)) { allErrors.push(error); } else { throw error; } handleOnRetryDelay({ onRetryDelay, error, waitTime: intervalAsTimeSpan, attempt, args, context, }); const remainingAfterValue = endDate.getTime() - Date.now(); if (remainingAfterValue <= 0) { return true; } await delay(intervalAsTimeSpan); return false; } /** * @internal */ function throwErrors(settings) { const { allErrors, throwLastError, attempt, timeAsTimeSpan, intervalAsTimeSpan, } = settings; if (allErrors.length !== 0 && !throwLastError) { throw RetryIntervalResilienceError.create(allErrors, attempt - 1, timeAsTimeSpan, intervalAsTimeSpan); } if (allErrors.length !== 0 && throwLastError) { throw allErrors.at(-1); } throw new UnexpectedError("retryInterval middleware reached an unreachble state, this is a bug please file issue on github."); } /** * IMPORT_PATH: `"@daiso-tech/core/resilience"` * @group Middlewares * @throws {RetryIntervalResilienceError} */ export function retryInterval(settings) { const { time, interval, errorPolicy, onRetryDelay = () => { }, onExecutionAttempt = () => { }, throwLastError = false, } = settings; const timeAsTimeSpan = TimeSpan.fromTimeSpan(time); const intervalAsTimeSpan = TimeSpan.fromTimeSpan(interval); return async ({ args, context, next }) => { const endDate = timeAsTimeSpan.toEndDate(); const allErrors = []; let attempt = 1; while (endDate.getTime() > new Date().getTime()) { try { const result = await handleWhenReturn({ onExecutionAttempt, attempt, args, context, next, errorPolicy, intervalAsTimeSpan, endDate, onRetryDelay, allErrors, }); if (result.type === "return") { return result.value; } if (result.type === "break") { break; } } catch (error) { if (await handleWhenThrow({ allErrors, error, errorPolicy, onRetryDelay, intervalAsTimeSpan, attempt, args, context, endDate, })) { break; } } finally { attempt++; } } throwErrors({ allErrors, throwLastError, attempt, timeAsTimeSpan, intervalAsTimeSpan, }); }; } //# sourceMappingURL=retry-interval.js.map