execution_policy 0.3.0
execution_policy: ^0.3.0 copied to clipboard
A Dart resilience and transient-fault-handling library (retry, backoff, timeout, circuit breaker, fallback) inspired by C# Polly.
Changelog #
0.3.0 - 2026-07-21 #
Fixed #
- Backoff overflow (critical): the exponential curve is now computed and
capped in
doublespace before jitter, so a large attempt count can no longer overflowint64into a negative/zero delay that bypassedmaxDelay. - Circuit breaker: rejects with a typed
CircuitOpenException(carryingretryAfter) instead of a bareStateError; half-open now admits exactly one probe (concurrent callers are rejected, preventing a thundering herd). - Fallback: catches only
Exceptions —Errorsubtypes (TypeError,StateError, …) propagate so real bugs stay visible. Added an optionalshouldHandlepredicate, and the fallback now receives the triggering error. - Retry hooks:
onErroris awaited defensively andretryIfis guarded, so a throwing/rejecting hook can never mask the real error or abort the retry loop. - Validation:
RetryPolicyrejectsmaxAttempts < 1at runtime (not only viaassert, which is stripped in release). - Jitter is applied after the
maxDelayclamp (so the capped tail still varies),Randomis instantiated once, and duplicate policy types in aPolicyBuildernow throw instead of sorting non-deterministically. TimeoutPolicy.executeisasync, so a synchronous throw from the action surfaces as aFutureerror rather than escaping synchronously.
Added #
CancellationToken— pass to.retry(cancelToken: …)to abort further attempts and interrupt a backoff that is already sleeping (e.g. from a widget'sdispose). AlsoshouldContinue— a cheap pre-backoff gate.- Observability:
onRetry(error, attempt, delay), circuit-breakeronStateChange(from, to), and read-onlystate/failureCountgetters.
Changed (breaking) #
PolicyBuilder.fallback/FallbackPolicy.fallbacktakeFuture<T> Function(Object error)(the error is passed in) — migrate() async => xto(_) async => x.CircuitBreakerPolicyopen state throwsCircuitOpenException, notStateError.- A
PolicyBuilderaccepts at most one policy of each type.
Notes #
- Composition order is fixed (
Fallback → CircuitBreaker → Retry → Timeout): timeout is per-attempt, breaker is outside retry. Reuse ONE builder per endpoint so the breaker accumulates state (a builder rebuilt per call never trips). - Full pre-release review:
docs/code-review-2026-07-21.md.
0.1.0 - 2025-07-06 #
Added #
- Initial release of execution_policy package
- RetryPolicy with fixed, linear, exponential, and jitter-ed backoff strategies
- TimeoutPolicy to enforce timeouts on async operations
- FallbackPolicy for fallback handling
- CircuitBreakerPolicy to prevent repeated failures
- PolicyBuilder for fluent chaining of policies
- PolicyDebugger for tracing and logging policy execution