using System.Reactive.Linq; namespace InnovEnergy.Lib.Utils; public static class ObservableExceptionHandling { public static IObservable<Try<R>> Try<T, R>(this IObservable<T> src, Func<T, Task<R>> map) { return src.SelectMany(t => ExceptionHandling.Try(() => map(t))); } public static IObservable<Try<R>> Try<T, R>(this IObservable<T> src, Func<T, R> map) { return src.Select(t => ExceptionHandling.Try(() => map(t))); } public static IObservable<Try<R>> ThenTry<T, R>(this IObservable<Try<T>> src, Func<T, R> map) { return src.Select(t => ExceptionHandling.ThenTry(t, map)); } // public static IObservable<T> Catch<T>(this IObservable<Try<T>> src, Func<Exception, T> onError) // { // return src.Select(t => ExceptionHandling.Catch(t, onError)); // } // TODO: onError should be a func returning T // public static IObservable<T> Catch<T>(this IObservable<Try<T>> src, Action<Exception> onError) // { // return src // .OnErrorDo(onError) // .IgnoreErrors(); // } public static IObservable<T> IgnoreErrors<T>(this IObservable<Try<T>> src) { return src .Where(t => !(t.Wrapped is Exception)) .Select(t => (T) t.Wrapped); } public static IObservable<Try<T>> OnErrorDo<T>(this IObservable<Try<T>> src, Action<Exception> onError) { return src.Do(t=> { if (t.Wrapped is Exception e) onError(e); }); } public static IObservable<Try<T>> Match<T>(this IObservable<Try<T>> src, Action<T> onValue, Action<Exception> onError) { return src.Do(t=> { if (t.Wrapped is Exception e) onError(e); else onValue((T) t.Wrapped); }); } // public static IObservable<CanFail<R>> Try<T,R>(this IObservable<T> observable, Func<T,R> map) // { // return observable // .Select(e => CanFail.Try(() => map(e))); // } // // public static IObservable<CanFail<R>> Try<T,R>(this IObservable<CanFail<T>> observable, Func<T,R> map) // { // return observable // .Select(t => t.Select(map)); // } // // // public static IObservable<CanFail<R>> TryAsync<T, R>(this IObservable<T> observable, Func<T, Task<R>> map) // { // return observable // .SelectMany(e => CanFail.TryAsync(() => map(e))); // } // // // public static IObservable<CanFail<R>> TryAsync<T,R>(this IObservable<CanFail<T>> observable, // Func<T,Task<R>> map) // { // return observable // .SelectMany(t => CanFail.SelectMany(t, map)); // } // // // public static IObservable<CanFail<T>> OnErrorDo<T>(this IObservable<CanFail<T>> observable, Action<Exception> onError) // { // return observable // .Select(t => // { // if (t is Failure<T> f) // onError(f.Error); // // return t; // }); // } // public static IObservable<R> TryCatch<T,R,E>(this IObservable<T> observable, // Func<T,R> map, // Func<E,R> exceptionHandler) // where E : Exception // { // R TryMap(T i) // { // try // { // return map(i); // } // catch (E e) // { // return exceptionHandler(e); // } // } // // return observable.Select(TryMap); // } // public static IObservable<CanFail<R>> Try<T,R,E>(this IObservable<T> observable, // Func<T,R> map, // Func<E, CanFail<R>> exceptionHandler) // where E : Exception // { // CanFail<R> TryMap(T i) // { // try // { // return CanFail.Success(map(i)); // } // catch (E e) // { // return exceptionHandler(e); // } // } // // return observable.Select(TryMap); // } // public static IObservable<R> TryAsync<T,R>(this IObservable<T> observable, // Func<T,Task<R>> map, // Action<Exception> onError) // { // async Task<Notification<R>> TryMap(T i) // { // try // { // return Notification.CreateOnNext(await map(i)); // } // catch (Exception e) // { // onError(e); // return Notification.CreateOnError<R>(e); // } // } // // return observable // .SelectMany(TryMap) // .Where(n => n.Kind != NotificationKind.OnError) // .Dematerialize(); // } // public static IObservable<R> Try<T,R>(this IObservable<T> observable, Func<T,R> map) // { // Notification<R> TryMap(T i) // { // try // { // return Notification.CreateOnNext(map(i)); // } // catch (Exception e) // { // return Notification.CreateOnError<R>(e); // } // } // // return observable // .Select(TryMap) // .Where(n => n.Kind != NotificationKind.OnError) // .Dematerialize(); // } // // public static IObservable<R> Try<T,R>(this IObservable<T> observable, // Func<T,R> map, // Action<Exception> onError) // { // Notification<R> TryMap(T i) // { // try // { // return Notification.CreateOnNext(map(i)); // } // catch (Exception e) // { // onError(e); // return Notification.CreateOnError<R>(e); // } // } // // return observable // .Select(TryMap) // .Where(n => n.Kind != NotificationKind.OnError) // .Dematerialize(); // } // // public static IObservable<R> Try<T,R>(this IObservable<T> observable, // Func<T,R> map, // Func<Exception,Boolean> ignoreException) // { // Notification<R> TryMap(T i) // { // try // { // return Notification.CreateOnNext(map(i)); // } // catch (Exception e) // { // if (ignoreException(e)) // return Notification.CreateOnError<R>(e); // // throw; // // // throw ex resets the stack trace (so your errors would appear to originate from HandleException) // // throw doesn't - the original offender would be preserved. // } // } // // return observable // .Select(TryMap) // .Where(n => n.Kind != NotificationKind.OnError) // .Dematerialize(); // } }