Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Polly-Contrib/Simmy/llms.txt

Use this file to discover all available pages before exploring further.

The InjectException policy is Simmy’s primary tool for fault injection: it intercepts calls made through a Polly policy and randomly throws a configured exception before the underlying code runs. This lets you verify that your retry policies, circuit breakers, and fallback handlers respond correctly to network errors, timeouts, or any other exception type — without waiting for those failures to occur naturally in production.

Factory method

InjectOutcomePolicy MonkeyPolicy.InjectException(
    Action<InjectOutcomeOptions<Exception>> configureOptions
)
The method accepts a fluent-builder callback that configures three required options — the fault to inject, the injection rate, and whether the policy is enabled — then returns a synchronous InjectOutcomePolicy instance ready for execution.

Quick start

1

Define the exception to inject

Create the exception object you want Simmy to throw. Any Exception subtype works.
var fault = new SocketException(errorCode: 10013);
2

Build the chaos policy

Use the fluent builder to wire up the fault, injection rate, and enabled flag.
var chaosPolicy = MonkeyPolicy.InjectException(with =>
    with.Fault(fault)
        .InjectionRate(0.05)
        .Enabled()
);
An injection rate of 0.05 means Simmy will throw the exception on roughly 5% of calls. .Enabled() hard-codes the policy as always active; you can pass a bool variable instead to toggle it at runtime.
3

Execute through the policy

Wrap your normal application code inside the policy exactly as you would with any Polly policy.
chaosPolicy.Execute(() => someMethod());
On approximately 5 in every 100 executions, someMethod() will not be called at all — Simmy throws the SocketException instead, letting your outer resilience policies handle it.

Fluent option methods

All three methods below are required when building an InjectException policy.

.Fault(exception)

Provides a fixed exception instance to throw. Simmy re-uses the same object on every injected call.

.InjectionRate(double)

A value between 0.0 and 1.0. The policy randomly injects the fault that proportion of the time.

.Enabled() / .Enabled(bool)

Activates the monkey policy. Pass false or a variable to pause injection without removing the policy.

Dynamic fault generation with a delegate

Instead of injecting a fixed exception, you can supply a Func<Context, CancellationToken, Exception> delegate. This lets you vary the exception type or message based on runtime state or the Polly Context attached to the current execution.
var chaosPolicy = MonkeyPolicy.InjectException(with =>
    with.Fault((ctx, ct) =>
            new HttpRequestException($"Simulated failure for operation: {ctx.OperationKey}"))
        .InjectionRate(0.1)
        .Enabled()
);

Dynamic injection rate and enabled flag

Both .InjectionRate and .EnabledWhen accept delegate overloads, so you can drive chaos settings from an external configuration source at runtime — no redeploy needed.
var chaosPolicy = MonkeyPolicy.InjectException(with =>
    with.Fault(new TimeoutException("Injected timeout"))
        .InjectionRate((ctx, ct) => GetInjectionRateFromConfig())
        .EnabledWhen((ctx, ct) => IsChaosEnabled(ctx, ct))
);

Async variant

For async/await code paths, use MonkeyPolicy.InjectExceptionAsync, which returns an AsyncInjectOutcomePolicy and accepts InjectOutcomeAsyncOptions<Exception>. The fluent builder methods are the same — .Fault(), .InjectionRate(), and .Enabled() — except that the delegate overloads for EnabledWhen and InjectionRate return Task rather than plain values.
var chaosPolicy = MonkeyPolicy.InjectExceptionAsync(with =>
    with.Fault(new SocketException(errorCode: 10013))
        .InjectionRate(0.05)
        .Enabled()
);

await chaosPolicy.ExecuteAsync(async ct => await someMethodAsync(ct), cancellationToken);

Using inside a PolicyWrap

Place the Simmy policy innermost inside a PolicyWrap so that your existing Polly resilience policies — retry, circuit-breaker, fallback — still apply and can handle the injected fault exactly as they would handle a real one.
var policyWrap = Policy.Wrap(fallbackPolicy, retryPolicy, chaosPolicy);
policyWrap.Execute(() => someMethod());
Simmy chaos policies are designed to sit innermost in a PolicyWrap. The outer Polly policies see the injected exception as a genuine failure, which is the whole point of chaos testing — your resilience code is exercised against it.

Enabling and disabling at runtime

The Enabled family of options gives you a safe way to keep chaos policies deployed in production without them constantly firing. Set a feature flag, environment variable, or configuration value and pass it through .Enabled(bool) or .EnabledWhen(Func<Context, CancellationToken, bool>).
// Hard-coded off — policy is deployed but does nothing
var chaosPolicy = MonkeyPolicy.InjectException(with =>
    with.Fault(new IOException("Disk full"))
        .InjectionRate(1.0)
        .Enabled(false)   // flip to true in a non-prod environment
);
Even with InjectionRate(1.0), setting .Enabled(false) means Simmy never injects anything. This pattern lets you deploy the policy to production and activate it selectively via external configuration.

Reference

See Policy Options for a full reference on all shared fluent option methods, including the Context-driven delegate overloads for InjectionRate and EnabledWhen.

Build docs developers (and LLMs) love