ProviderFailurePolicy
NexusLabs.Needlr.AgentFramework¶
NexusLabs.Needlr.AgentFramework.Providers¶
ProviderFailurePolicy Class¶
Declarative failure-handling rule applied by TieredProviderSelector<TQuery,TResult> when a provider throws an exception during ExecuteAsync(TQuery, CancellationToken).
public sealed record ProviderFailurePolicy : System.IEquatable<NexusLabs.Needlr.AgentFramework.Providers.ProviderFailurePolicy>
Inheritance System.Object 🡒 ProviderFailurePolicy
Implements System.IEquatable<ProviderFailurePolicy>
Example¶
// Treat ApiAuthException like ProviderUnavailableException, but skip for 5 minutes
// and emit a structured log.
var policy = new ProviderFailurePolicy(
Match: ex => ex is ApiAuthException,
SkipDuration: TimeSpan.FromMinutes(5),
OnHit: ctx =>
{
logger.LogWarning(ctx.Exception, "Provider {Provider} skipped until {Until}",
ctx.ProviderName, ctx.SkipUntil);
return ValueTask.CompletedTask;
});
var options = TieredProviderSelectorOptions.Default with
{
FailurePolicies = [.. TieredProviderSelectorOptions.Default.FailurePolicies, policy],
};
Remarks¶
Policies are evaluated in order against the thrown exception (first match wins). The first policy whose Match predicate returns true causes the selector to: 1. Add a per-provider attempt diagnostic to the chain and continue to the next provider. 2. Mark the provider as skipped for the duration in SkipDuration (if non-null), so subsequent calls bypass it without an attempt until the skip window elapses. 3. Invoke the OnHit callback (if non-null) with a ProviderFailureContext describing the failure.
If no policy matches the thrown exception, the selector re-throws the exception unchanged. The default policy in Default matches ProviderUnavailableException with no skip and no callback, preserving the framework's historical fall-through behaviour.
Cancellation is not subject to policy matching: the selector skips policy evaluation entirely when the active System.Threading.CancellationToken has been cancelled, so cancelled calls always propagate System.OperationCanceledException directly to the caller.
Callback exceptions propagate. If OnHit throws, the selector still releases quota for the failed attempt (the release happens in a finally block) and the callback's exception escapes ExecuteAsync(TQuery, CancellationToken). Subsequent providers are not attempted for that call.
Constructors¶
ProviderFailurePolicy(Predicate<Exception>, Nullable<TimeSpan>, Func<ProviderFailureContext,ValueTask>) Constructor¶
Declarative failure-handling rule applied by TieredProviderSelector<TQuery,TResult> when a provider throws an exception during ExecuteAsync(TQuery, CancellationToken).
public ProviderFailurePolicy(System.Predicate<System.Exception> Match, System.Nullable<System.TimeSpan> SkipDuration=null, System.Func<NexusLabs.Needlr.AgentFramework.Providers.ProviderFailureContext,System.Threading.Tasks.ValueTask>? OnHit=null);
Parameters¶
Match System.Predicate<System.Exception>
Predicate evaluated against each thrown exception to determine whether this policy applies. The first matching policy in FailurePolicies wins.
SkipDuration System.Nullable<System.TimeSpan>
Optional duration the failing provider should be skipped before being retried on
subsequent calls.
- null — no cross-call skip; the provider is retried on the next call.
- A finite System.TimeSpan — the provider is skipped until now + SkipDuration.
- IndefiniteSkip (System.TimeSpan.MaxValue) — the provider is skipped until process restart (resolves to System.DateTimeOffset.MaxValue; the selector clamps the addition to avoid overflow).
OnHit System.Func<ProviderFailureContext,System.Threading.Tasks.ValueTask>
Optional async callback invoked after the policy match is recorded but before fall-through to the next provider. Receives a ProviderFailureContext describing the failed provider, the exception, and the resulting skip-until timestamp (if any).
Example¶
// Treat ApiAuthException like ProviderUnavailableException, but skip for 5 minutes
// and emit a structured log.
var policy = new ProviderFailurePolicy(
Match: ex => ex is ApiAuthException,
SkipDuration: TimeSpan.FromMinutes(5),
OnHit: ctx =>
{
logger.LogWarning(ctx.Exception, "Provider {Provider} skipped until {Until}",
ctx.ProviderName, ctx.SkipUntil);
return ValueTask.CompletedTask;
});
var options = TieredProviderSelectorOptions.Default with
{
FailurePolicies = [.. TieredProviderSelectorOptions.Default.FailurePolicies, policy],
};
Remarks¶
Policies are evaluated in order against the thrown exception (first match wins). The first policy whose Match predicate returns true causes the selector to: 1. Add a per-provider attempt diagnostic to the chain and continue to the next provider. 2. Mark the provider as skipped for the duration in SkipDuration (if non-null), so subsequent calls bypass it without an attempt until the skip window elapses. 3. Invoke the OnHit callback (if non-null) with a ProviderFailureContext describing the failure.
If no policy matches the thrown exception, the selector re-throws the exception unchanged. The default policy in Default matches ProviderUnavailableException with no skip and no callback, preserving the framework's historical fall-through behaviour.
Cancellation is not subject to policy matching: the selector skips policy evaluation entirely when the active System.Threading.CancellationToken has been cancelled, so cancelled calls always propagate System.OperationCanceledException directly to the caller.
Callback exceptions propagate. If OnHit throws, the selector still releases quota for the failed attempt (the release happens in a finally block) and the callback's exception escapes ExecuteAsync(TQuery, CancellationToken). Subsequent providers are not attempted for that call.
Properties¶
ProviderFailurePolicy.IndefiniteSkip Property¶
Sentinel value for SkipDuration meaning "skip indefinitely
(until the host process restarts)." Resolves to
System.DateTimeOffset.MaxValue in the selector's skip cache; the
selector clamps the now + SkipDuration addition so passing this value
will not overflow.
Property Value¶
ProviderFailurePolicy.Match Property¶
Predicate evaluated against each thrown exception to determine whether this policy applies. The first matching policy in FailurePolicies wins.
Property Value¶
System.Predicate<System.Exception>
ProviderFailurePolicy.OnHit Property¶
Optional async callback invoked after the policy match is recorded but before fall-through to the next provider. Receives a ProviderFailureContext describing the failed provider, the exception, and the resulting skip-until timestamp (if any).
public System.Func<NexusLabs.Needlr.AgentFramework.Providers.ProviderFailureContext,System.Threading.Tasks.ValueTask>? OnHit { get; init; }
Property Value¶
System.Func<ProviderFailureContext,System.Threading.Tasks.ValueTask>
ProviderFailurePolicy.SkipDuration Property¶
Optional duration the failing provider should be skipped before being retried on
subsequent calls.
- null — no cross-call skip; the provider is retried on the next call.
- A finite System.TimeSpan — the provider is skipped until now + SkipDuration.
- IndefiniteSkip (System.TimeSpan.MaxValue) — the provider is skipped until process restart (resolves to System.DateTimeOffset.MaxValue; the selector clamps the addition to avoid overflow).