* feat(cron): add failure destination support with webhook mode and bestEffort handling Extends PR #24789 failure alerts with features from PR #29145: - Add webhook delivery mode for failure alerts (mode: 'webhook') - Add accountId support for multi-account channel configurations - Add bestEffort handling to skip alerts when job has bestEffort=true - Add separate failureDestination config (global + per-job in delivery) - Add duplicate prevention (prevents sending to same as primary delivery) - Add CLI flags: --failure-alert-mode, --failure-alert-account-id - Add UI fields for new options in web cron editor * fix(cron): merge failureAlert mode/accountId and preserve failureDestination on updates - Fix mergeCronFailureAlert to merge mode and accountId fields - Fix mergeCronDelivery to preserve failureDestination on updates - Fix isSameDeliveryTarget to use 'announce' as default instead of 'none' to properly detect duplicates when delivery.mode is undefined * fix(cron): validate webhook mode requires URL in resolveFailureDestination When mode is 'webhook' but no 'to' URL is provided, return null instead of creating an invalid plan that silently fails later. * fix(cron): fail closed on webhook mode without URL and make failureDestination fields clearable - sendCronFailureAlert: fail closed when mode is webhook but URL is missing - mergeCronDelivery: use per-key presence checks so callers can clear nested failureDestination fields via cron.update Note: protocol:check shows missing internalEvents in Swift models - this is a pre-existing issue unrelated to these changes (upstream sync needed). * fix(cron): use separate schema for failureDestination and fix type cast - Create CronFailureDestinationSchema excluding after/cooldownMs fields - Fix type cast in sendFailureNotificationAnnounce to use CronMessageChannel * fix(cron): merge global failureDestination with partial job overrides When job has partial failureDestination config, fall back to global config for unset fields instead of treating it as a full override. * fix(cron): avoid forcing announce mode and clear inherited to on mode change - UI: only include mode in patch if explicitly set to non-default - delivery.ts: clear inherited 'to' when job overrides mode, since URL semantics differ between announce and webhook modes * fix(cron): preserve explicit to on mode override and always include mode in UI patches - delivery.ts: preserve job-level explicit 'to' when overriding mode - UI: always include mode in failureAlert patch so users can switch between announce/webhook * fix(cron): allow clearing accountId and treat undefined global mode as announce - UI: always include accountId in patch so users can clear it - delivery.ts: treat undefined global mode as announce when comparing for clearing inherited 'to' * Cron: harden failure destination routing and add regression coverage * Cron: resolve failure destination review feedback * Cron: drop unrelated timeout assertions from conflict resolution * Cron: format cron CLI regression test * Cron: align gateway cron test mock types --------- Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
59 lines
1.8 KiB
TypeScript
59 lines
1.8 KiB
TypeScript
/** Error types that can trigger retries for one-shot jobs. */
|
|
export type CronRetryOn = "rate_limit" | "network" | "timeout" | "server_error";
|
|
|
|
export type CronRetryConfig = {
|
|
/** Max retries for transient errors before permanent disable (default: 3). */
|
|
maxAttempts?: number;
|
|
/** Backoff delays in ms for each retry attempt (default: [30000, 60000, 300000]). */
|
|
backoffMs?: number[];
|
|
/** Error types to retry; omit to retry all transient types. */
|
|
retryOn?: CronRetryOn[];
|
|
};
|
|
|
|
export type CronFailureAlertConfig = {
|
|
enabled?: boolean;
|
|
after?: number;
|
|
cooldownMs?: number;
|
|
mode?: "announce" | "webhook";
|
|
accountId?: string;
|
|
};
|
|
|
|
export type CronFailureDestinationConfig = {
|
|
channel?: string;
|
|
to?: string;
|
|
accountId?: string;
|
|
mode?: "announce" | "webhook";
|
|
};
|
|
|
|
export type CronConfig = {
|
|
enabled?: boolean;
|
|
store?: string;
|
|
maxConcurrentRuns?: number;
|
|
/** Override default retry policy for one-shot jobs on transient errors. */
|
|
retry?: CronRetryConfig;
|
|
/**
|
|
* Deprecated legacy fallback webhook URL used only for stored jobs with notify=true.
|
|
* Prefer per-job delivery.mode="webhook" with delivery.to.
|
|
*/
|
|
webhook?: string;
|
|
/** Bearer token for cron webhook POST delivery. */
|
|
webhookToken?: string;
|
|
/**
|
|
* How long to retain completed cron run sessions before automatic pruning.
|
|
* Accepts a duration string (e.g. "24h", "7d", "1h30m") or `false` to disable pruning.
|
|
* Default: "24h".
|
|
*/
|
|
sessionRetention?: string | false;
|
|
/**
|
|
* Run-log pruning controls for `cron/runs/<jobId>.jsonl`.
|
|
* Defaults: `maxBytes=2_000_000`, `keepLines=2000`.
|
|
*/
|
|
runLog?: {
|
|
maxBytes?: number | string;
|
|
keepLines?: number;
|
|
};
|
|
failureAlert?: CronFailureAlertConfig;
|
|
/** Default destination for failure notifications across all cron jobs. */
|
|
failureDestination?: CronFailureDestinationConfig;
|
|
};
|