Observable.ErrorHandling.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UniRx.Operators;
  5. namespace UniRx
  6. {
  7. public static partial class Observable
  8. {
  9. public static IObservable<T> Finally<T>(this IObservable<T> source, Action finallyAction)
  10. {
  11. return new FinallyObservable<T>(source, finallyAction);
  12. }
  13. public static IObservable<T> Catch<T, TException>(this IObservable<T> source, Func<TException, IObservable<T>> errorHandler)
  14. where TException : Exception
  15. {
  16. return new CatchObservable<T, TException>(source, errorHandler);
  17. }
  18. public static IObservable<TSource> Catch<TSource>(this IEnumerable<IObservable<TSource>> sources)
  19. {
  20. return new CatchObservable<TSource>(sources);
  21. }
  22. /// <summary>Catch exception and return Observable.Empty.</summary>
  23. public static IObservable<TSource> CatchIgnore<TSource>(this IObservable<TSource> source)
  24. {
  25. return source.Catch<TSource, Exception>(Stubs.CatchIgnore<TSource>);
  26. }
  27. /// <summary>Catch exception and return Observable.Empty.</summary>
  28. public static IObservable<TSource> CatchIgnore<TSource, TException>(this IObservable<TSource> source, Action<TException> errorAction)
  29. where TException : Exception
  30. {
  31. var result = source.Catch((TException ex) =>
  32. {
  33. errorAction(ex);
  34. return Observable.Empty<TSource>();
  35. });
  36. return result;
  37. }
  38. public static IObservable<TSource> Retry<TSource>(this IObservable<TSource> source)
  39. {
  40. return RepeatInfinite(source).Catch();
  41. }
  42. public static IObservable<TSource> Retry<TSource>(this IObservable<TSource> source, int retryCount)
  43. {
  44. return System.Linq.Enumerable.Repeat(source, retryCount).Catch();
  45. }
  46. /// <summary>
  47. /// <para>Repeats the source observable sequence until it successfully terminates.</para>
  48. /// <para>This is same as Retry().</para>
  49. /// </summary>
  50. public static IObservable<TSource> OnErrorRetry<TSource>(
  51. this IObservable<TSource> source)
  52. {
  53. var result = source.Retry();
  54. return result;
  55. }
  56. /// <summary>
  57. /// When catched exception, do onError action and repeat observable sequence.
  58. /// </summary>
  59. public static IObservable<TSource> OnErrorRetry<TSource, TException>(
  60. this IObservable<TSource> source, Action<TException> onError)
  61. where TException : Exception
  62. {
  63. return source.OnErrorRetry(onError, TimeSpan.Zero);
  64. }
  65. /// <summary>
  66. /// When catched exception, do onError action and repeat observable sequence after delay time.
  67. /// </summary>
  68. public static IObservable<TSource> OnErrorRetry<TSource, TException>(
  69. this IObservable<TSource> source, Action<TException> onError, TimeSpan delay)
  70. where TException : Exception
  71. {
  72. return source.OnErrorRetry(onError, int.MaxValue, delay);
  73. }
  74. /// <summary>
  75. /// When catched exception, do onError action and repeat observable sequence during within retryCount.
  76. /// </summary>
  77. public static IObservable<TSource> OnErrorRetry<TSource, TException>(
  78. this IObservable<TSource> source, Action<TException> onError, int retryCount)
  79. where TException : Exception
  80. {
  81. return source.OnErrorRetry(onError, retryCount, TimeSpan.Zero);
  82. }
  83. /// <summary>
  84. /// When catched exception, do onError action and repeat observable sequence after delay time during within retryCount.
  85. /// </summary>
  86. public static IObservable<TSource> OnErrorRetry<TSource, TException>(
  87. this IObservable<TSource> source, Action<TException> onError, int retryCount, TimeSpan delay)
  88. where TException : Exception
  89. {
  90. return source.OnErrorRetry(onError, retryCount, delay, Scheduler.DefaultSchedulers.TimeBasedOperations);
  91. }
  92. /// <summary>
  93. /// When catched exception, do onError action and repeat observable sequence after delay time(work on delayScheduler) during within retryCount.
  94. /// </summary>
  95. public static IObservable<TSource> OnErrorRetry<TSource, TException>(
  96. this IObservable<TSource> source, Action<TException> onError, int retryCount, TimeSpan delay, IScheduler delayScheduler)
  97. where TException : Exception
  98. {
  99. var result = Observable.Defer(() =>
  100. {
  101. var dueTime = (delay.Ticks < 0) ? TimeSpan.Zero : delay;
  102. var count = 0;
  103. IObservable<TSource> self = null;
  104. self = source.Catch((TException ex) =>
  105. {
  106. onError(ex);
  107. return (++count < retryCount)
  108. ? (dueTime == TimeSpan.Zero)
  109. ? self.SubscribeOn(Scheduler.CurrentThread)
  110. : self.DelaySubscription(dueTime, delayScheduler).SubscribeOn(Scheduler.CurrentThread)
  111. : Observable.Throw<TSource>(ex);
  112. });
  113. return self;
  114. });
  115. return result;
  116. }
  117. }
  118. }