louthy/language-ext · info · OperationCanceledException
OperationCanceledException
Error message
OperationCanceledException
What it means
IO.cancel (IO.Prelude) is an IO<Unit> that cancels the ambient CancellationTokenSource and then throws OperationCanceledException. It is the library's intended way to abort an IO computation; the exception is the cancellation signal, not a bug.
Solutions
- If cancellation is intended, catch OperationCanceledException (or use IO.Catch with a cancellation filter) at the top of the flow
- Check Token.IsCancellationRequested via the IO environment instead of hard-throwing when you want graceful shutdown
- Ensure bracket/finalizer logic (Bracket/BracketFail) is used so resources are released on cancellation
- Do not swallow OperationCanceledException generically with catch(Exception); rethrow or filter it
Example fix
// before var io = work.Bind(_ => IO.cancel); // unwinds with OperationCanceledException // after var io = work.Bind(_ => IO.cancel).Catch(OperationCanceledException (_)=> IO.unit); // or handle at boundary
Defensive patterns
Strategy: try-catch
Validate before calling
// No pre-check possible: evaluating IO.cancel always throws; branch conditionally instead
if (shouldStop) { /* choose a non-throwing IO path */ } Type guard
bool IsCancelled(Exception e) => e is OperationCanceledException;
Try / catch
try { result = io.Run(env); }
catch (OperationCanceledException) { /* expected cancellation path */ } Prevention
- Use IO.cancel deliberately and document it at the composition boundary
- Never catch bare Exception in ways that swallow OperationCanceledException
- Use Bracket so finalizers run on cancellation
- Prefer token-based checks for graceful shutdown instead of hard throws
When it happens
Trigger: Evaluating the `cancel` IO value, directly or as part of a larger IO chain (e.g. io.Bind(_ => IO.cancel)), which calls e.Source.Cancel() and throws OperationCanceledException.
Common situations: Deliberately aborting long-running IO flows, wiring a cancellation branch into a selective/awaitAny-style composition, or accidentally including `cancel` in a pipeline that then unwinds.
Related errors
- OperationCanceledException
- OperationCanceledException
- OperationCanceledException
- OperationCanceledException
- -2000000007
AI-assisted analysis of louthy/language-ext@2f0e362824 (2026-09-15).
Data as JSON: /api/errors/5a81f34b70548924.
Report an issue: GitHub.
Appendix: source
Thrown at LanguageExt.Core/Effects/IO/Prelude/IO.Prelude.cs:30
public static partial class Prelude
{
/// <summary>
/// Access the cancellation-token from the IO environment
/// </summary>
/// <returns>CancellationToken</returns>
public static readonly IO<CancellationToken> cancelToken =
IO.lift(e => e.Token);
/// <summary>
/// Request a cancellation of the IO expression
/// </summary>
public static readonly IO<Unit> cancel =
IO.lift<Unit>(
e =>
{
e.Source.Cancel();
throw new OperationCanceledException();
});
/// <summary>
/// Always yields a `Unit` value
/// </summary>
public static readonly IO<Unit> unitIO =
IO.pure<Unit>(default);
/// <summary>
/// Yields the IO environment
/// </summary>
public static readonly IO<EnvIO> envIO =
IO.lift<EnvIO>(e => e);
/// <summary>
/// Tail call
/// </summary>
/// <param name="tailIO"></param>View on GitHub (pinned to 2f0e362824)