Search code examples
c#functional-programminglanguage-ext

Language-ext Aggregate exceptions/failures when Try<IEnumerable<Try<...>>>


I am fresh new with the brilliant language-ext c# library.

I have this code that returns a Try<IEnumerable<Try<Unit>> object:

            Try(DetectAlertsToNotify)
            .MapT(SendNotification)
            //treat errors happened indifferently from their source

Edit: DetectAlertsToNotify returns an IEnumerable of AlertDTO

What I would like to achieve is to process elegantly all exceptions or maybe the first exception whatever it happened in DetectAlertsToNotify or SendNotification.

How could I aggregate all errors or take the first error of Try<IEnumerable<Try<Unit>> with keeping code simple and minimum as possible?


Solution

  • Maybe you're looking for something like this:

    using LanguageExt;
    using static LanguageExt.Prelude;
    
    Try<Unit> Send(string message)
    {
        return Try(unit);
    }
    
    Try<Arr<string>> GetList()
    {
        return Try(Array("a", "b", "c"));
    }
    
    // LINQ style (better for longer chains)
    var errorOrAllResults1 =
        from inputs in GetList()
        from results in inputs.Map(Send).Sequence()
        select results;
    
    // method style
    var errorOrAllResults2 = GetList().Bind(inputs => inputs.Map(Send).Sequence());
    
    

    Notes:

    • I use Arr<T> instead of IEnumerable<T> because this makes sure there is no enumeration outside of Try in case the exception might raise when enumerating. Otherwise we probably need some helper to make sure the enumeration itself is catched in some Try.
    • Sequence() will change inner and outer monad (container). This turns Arr<Try<Unit>> into Try<Arr<Unit>>. We need this because we want/need to "stay" in the Try monad (LINQ expression).

    If you look at the intermediate types you probably will get the idea.