public static async Task InvokeAsync(RetryPolicy retryPolicy, Action action) { if (action == null) { throw new ArgumentNullException(nameof(action)); } if (retryPolicy == null) { throw new ArgumentNullException(nameof(retryPolicy)); } var session = new RetrySession(retryPolicy); session.Begin(); Exception exception = null; var complete = false; while (!complete) { try { action(); complete = true; } //todo: test if the three catch methods are required to correctly resolve the exception. catch (TargetInvocationException ex) { exception = ex.GetPrimaryException(); } catch (AggregateException ex) { exception = ex.GetPrimaryException(); } catch (Exception ex) { exception = ex.GetPrimaryException(); } // test the exception for can retry, exceeded max retry, and timeout if (exception != null) { var retryException = session.CheckException(exception); if (retryException != null) { Debug.WriteLine($"{nameof(WithRetry)}.{nameof(InvokeAsync)} encountered exception '{exception.GetType().Name}' with message '{exception.Message}' - CAN'T RETRY"); throw retryException; } // wait a bit before trying again Debug.WriteLine($"{nameof(WithRetry)}.{nameof(InvokeAsync)} encountered exception '{exception.GetType().Name}' with message '{exception.Message}' - CAN RETRY AFTER SLEEP"); await session.SleepAsync(); //reset exception for next attempt exception = null; } } // while (!complete) }
protected override object Invoke(MethodInfo targetMethod, object[] args) { object result = null; var session = new RetrySession(_retryPolicy) .Begin(); Exception exception = null; var complete = false; while (!complete) { try { var isAwaitable = targetMethod.ReturnType.GetMethod(nameof(Task.GetAwaiter)) != null; result = isAwaitable ? InvokeAsynchronous(targetMethod, args) : InvokeSynchronous(targetMethod, args); //result = targetMethod.Invoke(_instance, args); complete = true; } catch (TargetInvocationException ex) { exception = ex.GetPrimaryException(); } catch (AggregateException ex) { exception = ex.GetPrimaryException(); } catch (Exception ex) { throw new RetryException(session, $"Unexpected exception type '{ex.GetType().FullName}'. See inner exception for details.", ex); } // test the exception for can retry, exceeded max retry, and timeout if (exception != null) { var retryException = session.CheckException(exception); if (retryException != null) { throw retryException; } // wait a bit before trying again session.Sleep(); //reset exception for next attempt exception = null; } } // while (!complete) session.End(); return(result); }
public RetryException(RetrySession retrySession) : base() { RetrySession = retrySession ?? throw new ArgumentNullException(nameof(retrySession)); RetrySession.End(); }
public ExceededMaxWaitTimeException(RetrySession retrySession, RetryPolicy retryPolicy, Exception innerException) : base(retrySession, retryPolicy, innerException) { }
public ExceededMaxWaitTimeException(RetrySession retrySession, RetryPolicy retryPolicy) : base(retrySession, retryPolicy) { }
public ExceededMaxAttemptsException(RetrySession retrySession, RetryPolicy retryPolicy, Exception innerException) : base(retrySession, retryPolicy, innerException) { }
public ExceededMaxAttemptsException(RetrySession retrySession, RetryPolicy retryPolicy) : base(retrySession, retryPolicy) { }
public RetryNotAllowedException(RetrySession retrySession, RetryPolicy retryPolicy, Exception innerException) : base(retrySession, innerException) { RetryPolicy = retryPolicy ?? throw new ArgumentNullException(nameof(retryPolicy)); }
public RetryException(RetrySession retrySession, Exception innerException) : this(retrySession, string.Empty, innerException) { }
public RetryException(RetrySession retrySession, string message, Exception innerException) : base(message, innerException) { RetrySession = retrySession ?? throw new ArgumentNullException(nameof(retrySession)); RetrySession.End(); }
internal RetrySession(RetrySession retrySession) : this(retrySession._retryPolicy) { Attempts = retrySession.Attempts; ElapsedTime = TimeSpan.FromTicks(retrySession.ElapsedTime.Ticks); Exceptions.AddRange(retrySession.Exceptions); }