Example #1
0
        private void TransformingErrorWithMapError()
        {
            ITry <int, NetworkOperationError> number = Api.GetNumber();

            // You can use MapError to map for example from exception to another type you use to represent errors. Or map to logging messages.
            ITry <int, string> flooredMultiplicationResult = number.MapError(e => e.ToString());
        }
Example #2
0
 public bool Equals(ITry <T> other)
 {
     return
         (other != null &&
          !other.IsValid &&
          _error.Equals(other.Error));
 }
Example #3
0
 /// <summary>
 /// Maps the successful result to a new try.
 /// </summary>
 public static ITry <B, E> FlatMap <A, E, B>(this ITry <A, E> t, Func <A, ITry <B, E> > f)
 {
     return(t.Match(
                s => f(s),
                e => Try.Error <B, E>(e)
                ));
 }
Example #4
0
        private static void CreatingTryDirectly()
        {
            // Note that we explicitly specify types of variables in the following examples. However, in practice, we use var.
            // Creates an ITry with successful result while specifying type of an error.
            ITry <int, NetworkOperationError> success = Try.Success <int, NetworkOperationError>(42);

            // Creates an ITry with erroneous result while specifying type of a success.
            ITry <int, NetworkOperationError> error = Try.Error <int, NetworkOperationError>(NetworkOperationError.NetworkIssues);

            // Creating a successful ITry while specifying type of an error.
            ITry <int, Exception> successTry = 42.ToTry < int, Exception > ();

            // Creating an erronous ITry directly from exception while specifying type of a success.
            ITry <int, Exception> errorTry = new Exception().ToTry <int, Exception>();

            // Converting an option to try.
            var option = Option.Empty <int>();
            ITry <int, Exception> tryFromOption = option.ToTry(_ => new Exception("No value was provided in the option."));
            ITry <int, string>    tryFromOptionWithErrorType = option.ToTry(_ => "No value was provided in the option.");

            // Generally collections are recommended for validations.
            // It is easy to aggregate validations of multiple values into one ITry of the whole object.
            // And then you either get the successfully parsed object or you have the list of errors.
            ITry <int, IEnumerable <string> > validationRepresentation = option.ToTry(_ => new[] { "No valid value was provided in the option." });
        }
Example #5
0
        private void AggregatingCollectionOfTries(int numberCount)
        {
            IEnumerable <ITry <int, NetworkOperationError> > numbers = Enumerable.Range(0, numberCount).Select(_ => Api.GetNumber());

            // Contains all the numbers if their retrieval succeeded. Or all the errors from the ones that failed. Success results are lost in such case.
            ITry <IEnumerable <int>, IEnumerable <NetworkOperationError> > combinedResult = Try.Aggregate(numbers);
        }
Example #6
0
        static void Main(string[] args)
        {
            ITry ThisMeaning = (ITry) new Meaning();        // This works

            ThisMeaning.foo();
            ThisMeaning.Dispose();       // The method is available
        }
Example #7
0
 public static ITry <T> Where <T>(this ITry <T> value, Func <T, bool> evaluator, Func <Unit, Exception> error)
 {
     return(value.FlatMap(v => evaluator(v).ToTry(
                              t => v,
                              f => error(Unit.Value)
                              )));
 }
Example #8
0
 /// <summary>
 /// If the successful result passes the predicate, returns the original try. Otherwise returns erroneous try with the specified result.
 /// </summary>
 public static ITry <A, E> Where <A, E>(this ITry <A, E> t, Func <A, bool> predicate, Func <Unit, E> otherwise)
 {
     return(t.FlatMap(a => predicate(a).Match(
                          _ => t,
                          _ => Try.Error <A, E>(otherwise(Unit.Value))
                          )));
 }
Example #9
0
 /// <summary>
 /// If the successful result passes the predicate, returns the original try. Otherwise returns erroneous try with the specified result.
 /// </summary>
 public static ITry <A, IEnumerable <E> > Where <A, E>(this ITry <A, IEnumerable <E> > t, Func <A, bool> predicate, Func <Unit, E> otherwise)
 {
     return(t.FlatMap(a => predicate(a).Match(
                          _ => t,
                          _ => Try.Error <A, IEnumerable <E> >(new[] { otherwise(Unit.Value) })
                          )));
 }
Example #10
0
        /// Causes this promise to be completed with <c>result</c>.
        public void Complete(ITry <T> result)
        {
            if (_result != null)
            {
                throw new InvalidOperationException("Already completed");
            }
            _result = result;

            if (_onComplete != null)
            {
                try {
                    var lners = _onComplete.GetInvocationList();
                    List <Exception> errors = null;
                    foreach (Action <ITry <T> > lner in lners)
                    {
                        try {
                            lner(_result);
                        } catch (Exception e) {
                            if (errors == null)
                            {
                                errors = new List <Exception>();
                            }
                            errors.Add(e);
                        }
                    }
                    if (errors != null)
                    {
                        throw new AggregateException(errors);
                    }
                } finally {
                    _onComplete = null;
                }
            }
        }
Example #11
0
 public bool Equals(ITry <T> other)
 {
     return
         (other != null &&
          other.IsValid &&
          _value.Equals(other.Value));
 }
Example #12
0
 public static ITry <T, INonEmptyEnumerable <E> > Where <T, E>(this ITry <T, INonEmptyEnumerable <E> > value, Func <T, bool> evaluator, Func <Unit, E> error)
 {
     return(value.FlatMap(v => evaluator(v).ToTry(
                              t => v,
                              f => error(Unit.Value).ToEnumerable()
                              )));
 }
Example #13
0
 /// <summary>
 /// If the result is success, returns it. Otherwise throws the result of the otherwise function.
 /// </summary>
 public static A Get <A, E>(this ITry <A, E> t, Func <E, Exception> otherwise)
 {
     return(t.Match(
                s => s,
                e => throw otherwise(e)
                ));
 }
Example #14
0
 public override void WriteJson(
     JsonWriter writer,
     ITry <object> value,
     JsonSerializer serializer) => value
 .Match(
     _ => FromObject(_, serializer),
     _ => FromObject(_, serializer))
 .WriteTo(writer);
 private IOption <UserMessage> ProcessResult(ITry <ShoppingListWithItems, CookRecipeError> result) =>
 result.Match(
     s => UpdateShoppingList(s).Pipe(_ => Option.Empty <UserMessage>()),
     e => Option.Create(e.Match(
                            CookRecipeError.NotEnoughFoodstuffsInShoppingList,
                            _ => UserMessages.NotEnoughFoodstuffsInShoppingList()
                            ))
     );
Example #16
0
        private void HandlingNestedTriesWithFlatMap()
        {
            ITry <int, NetworkOperationError> number = Api.GetNumber();
            ITry <ITry <int, NetworkOperationError>, NetworkOperationError> doubleNumber = number.Map(r => Api.DoubleNumber(r));

            // This try succeeds only if both tries succeed. However the second lambda is only executed in case the first try is successful.
            ITry <int, NetworkOperationError> doubleNumberFlattened = number.FlatMap(r => Api.DoubleNumber(r));
        }
Example #17
0
 /// <summary>
 /// Aggregates the tries using the specified function if all of them are successful. Otherwise aggregates all errors into error result by concatenation.
 /// </summary>
 public static ITry <R, IEnumerable <E> > Aggregate <A1, A2, A3, A4, R, E>(ITry <A1, IEnumerable <E> > t1, ITry <A2, IEnumerable <E> > t2, ITry <A3, IEnumerable <E> > t3, ITry <A4, IEnumerable <E> > t4, Func <A1, A2, A3, A4, R> success)
 {
     return(Aggregate(
                t1, t2, t3, t4,
                success: (s1, s2, s3, s4) => Success <R, IEnumerable <E> >(success(s1, s2, s3, s4)),
                error: errors => Error <R, IEnumerable <E> >(errors.SelectMany(e => e).ToList())
                ));
 }
 private UserActionResult ToUserActionResult(ITry <Unit, SignInError> t) =>
 t.Match(
     s => UserActionResult.Success(),
     e => e.Match(
         SignInError.InvalidCredentials, _ => UserActionResult.Error(UserMessages.InvalidCredentials()),
         SignInError.NoConnection, _ => UserActionResult.Error(UserMessages.NoConnection())
         )
     );
Example #19
0
 /// <summary>
 /// Aggregates the tries using the specified function if all of them are successful. Otherwise aggregates all errors into error result by concatenation.
 /// </summary>
 public static ITry <R, IEnumerable <E> > Aggregate <A1, A2, A3, R, E>(ITry <A1, E> t1, ITry <A2, E> t2, ITry <A3, E> t3, Func <A1, A2, A3, R> success)
 {
     return(Aggregate(
                t1, t2, t3,
                success: (s1, s2, s3) => Success <R, IEnumerable <E> >(success(s1, s2, s3)),
                error: errors => Error <R, IEnumerable <E> >(errors)
                ));
 }
Example #20
0
        public static ITry <T> Do <T>(this ITry <T> original, Action <T> execute)
        {
            if (original is Success <T> success)
            {
                execute(success.Value);
            }

            return(original);
        }
Example #21
0
 /// <summary>
 /// Maps the error result to a new try.
 /// </summary>
 public static ITry <B, F> FlatMapError <A, E, B, F>(this ITry <A, E> t, Func <E, ITry <B, F> > f)
     where A : B
     where E : F
 {
     return(t.Match(
                s => Try.Success <B, F>(s),
                e => f(e)
                ));
 }
Example #22
0
        public static ITry <T> DoError <T>(this ITry <T> original, Action <string> execute)
        {
            if (original is Failure <T> error)
            {
                execute(error.Message);
            }

            return(original);
        }
Example #23
0
 private UserActionResult ToUserActionResult(ITry <Unit, SignUpError[]> t) =>
 t.Match(
     s => UserActionResult.Success(),
     e => e.First().Match(
         SignUpError.NoConnection, _ => UserActionResult.Error(UserMessages.NoConnection()),
         SignUpError.InvalidEmail, _ => Email.Invalidate().Pipe(u => UserActionResult.Error()),
         SignUpError.PasswordTooShort, _ => Password.Invalidate().Pipe(u => UserActionResult.Error()),
         SignUpError.AccountAlreadyExists, _ => UserActionResult.Error(UserMessages.AccountAlreadyExists())
         )
     );
Example #24
0
        public static Tuple <bool, Exception> MatchFailure <T>(ITry <T> candidate)
        {
            var fail = candidate as Failure <T>;

            if (fail != null)
            {
                return(Tuple.Create(true, fail.GetException()));
            }
            return(Tuple.Create <bool, Exception>(false, null));
        }
Example #25
0
 /// <summary>
 /// Return the first success otherwise concatenate the error messages of both failures.
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="original"></param>
 /// <param name="fn"></param>
 /// <returns></returns>
 public static ITry <T> SelectFirstSuccess <T>(this ITry <T> original, Func <ITry <T> > fn) =>
 original.Match(
     success: (val) => original,
     failure: (firstError) =>
     fn().Let(
         secondResult => secondResult.Match(
             success: (_) => secondResult,
             failure: (secondError) => Try.Failure <T>(String.Concat(firstError, ", ", secondError))
             )
         )
     );
Example #26
0
        /// <summary>
        /// Aggregates the tries using the specified function if all of them are successful. Otherwise aggregates the errors by the specified function.
        /// </summary>
        public static R Aggregate <A1, A2, A3, A4, A5, A6, E, R>(ITry <A1, E> t1, ITry <A2, E> t2, ITry <A3, E> t3, ITry <A4, E> t4, ITry <A5, E> t5, ITry <A6, E> t6, Func <A1, A2, A3, A4, A5, A6, R> success, Func <IEnumerable <E>, R> error)
        {
            if (t1.IsSuccess && t2.IsSuccess && t3.IsSuccess && t4.IsSuccess && t5.IsSuccess && t6.IsSuccess)
            {
                return(success(t1.Success.Get(), t2.Success.Get(), t3.Success.Get(), t4.Success.Get(), t5.Success.Get(), t6.Success.Get()));
            }

            var errors = new[] { t1.Error, t2.Error, t3.Error, t4.Error, t5.Error, t6.Error };

            return(error(errors.Flatten().ToList()));
        }
Example #27
0
        /// <summary>
        /// Aggregates the tries using the specified function if all of them are successful. Otherwise aggregates the errors by the specified function.
        /// </summary>
        public static R Aggregate <A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, E, R>(ITry <A1, E> t1, ITry <A2, E> t2, ITry <A3, E> t3, ITry <A4, E> t4, ITry <A5, E> t5, ITry <A6, E> t6, ITry <A7, E> t7, ITry <A8, E> t8, ITry <A9, E> t9, ITry <A10, E> t10, Func <A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, R> success, Func <IEnumerable <E>, R> error)
        {
            if (t1.IsSuccess && t2.IsSuccess && t3.IsSuccess && t4.IsSuccess && t5.IsSuccess && t6.IsSuccess && t7.IsSuccess && t8.IsSuccess && t9.IsSuccess && t10.IsSuccess)
            {
                return(success(t1.Success.Get(), t2.Success.Get(), t3.Success.Get(), t4.Success.Get(), t5.Success.Get(), t6.Success.Get(), t7.Success.Get(), t8.Success.Get(), t9.Success.Get(), t10.Success.Get()));
            }

            var errors = new[] { t1.Error, t2.Error, t3.Error, t4.Error, t5.Error, t6.Error, t7.Error, t8.Error, t9.Error, t10.Error };

            return(error(errors.Flatten().ToList()));
        }
Example #28
0
        /// <summary>
        /// Aggregates the tries using the specified function if all of them are successful. Otherwise aggregates the errors by the specified function.
        /// </summary>
        public static R Aggregate <A1, A2, E, R>(ITry <A1, E> t1, ITry <A2, E> t2, Func <A1, A2, R> success, Func <IEnumerable <E>, R> error)
        {
            if (t1.IsSuccess && t2.IsSuccess)
            {
                return(success(t1.Success.Get(), t2.Success.Get()));
            }

            var errors = new[] { t1.Error, t2.Error };

            return(error(errors.Flatten().ToList()));
        }
Example #29
0
 /// <summary>
 /// If the result is success, returns it. Otherwise throws the exception.
 /// </summary>
 public static A Get <A, E>(this ITry <A, E> t)
     where E : Exception
 {
     return(t.Match(
                s => s,
                e =>
     {
         ExceptionDispatchInfo.Capture(e).Throw();
         return default;
     }
                ));
 }
Example #30
0
        public static void HandlingExceptionsWithCatch(decimal number, decimal divisor)
        {
            // Catches any exception and stores the single exception into the try.
            // This is useful for handling individual errors, but cannot be aggregated.
            ITry <decimal, Exception> divisionHandlingAllExceptions = Try.Catch <decimal, Exception>(_ => number / divisor);

            // Only catches a specific exception. Notice that the error type is the specific type of exception, not a collection of exceptions.
            ITry <decimal, DivideByZeroException> divisionHandlingDividingByZero = Try.Catch <decimal, DivideByZeroException>(_ => number / divisor);

            // Catch also has an overload which allows recovering in case of exception. Serves as standard try/catch, but returns a value.
            decimal divisionResult = Try.Catch <decimal, DivideByZeroException>(
                _ => number / divisor,
                exception => 0
                );
        }