public static AsyncPolicy <T> AlteredRetryPolicy <T>(this PolicyBuilder <T> p, string name) where T : IAlteredResponse => Policy.WrapAsync( p.WaitAndRetryAsync( DecorrelatedJitter(MaxRetries, MinDelay, MaxDelay), (response, timeSpan, numRetries, context) => { AlteredLog.Warning(new { Name = name, response.Result.RequestId, Response = new { StatusCode = (int)RetryStatusCode, response.Result.RequestDuration, RetryAfter = timeSpan.TotalMilliseconds, NumRetries = numRetries, Context = context.ToDictionary() // response.Exception? already logged } }); }), p.CircuitBreakerAsync(MaxCircuitFails, CircuitBreakDuration, (response, state, timeSpan, context) => { AlteredLog.Error(new { Name = name, response.Result.RequestId, Response = new { StatusCode = (int)CircuitBreakStatusCode, response.Result.RequestDuration, RetryAfter = timeSpan.TotalMilliseconds, CircuitState = state, Context = context.ToDictionary() } }); }, (context) => { AlteredLog.Error(new { Name = name, Response = new { StatusCode = (int)CircuitResetStatusCode, Context = context.ToDictionary() } }); }, () => { // half-open }));
public static Func <TRequest, Task <TResponse> > WithUnhandledException <TRequest, TResponse, TException>(this Func <TRequest, Task <TResponse> > func, string name, Func <TException, StatusCode> getErrorCode = null) where TRequest : IRequestId where TResponse : IStatusCode, new() where TException : Exception => async(request) => { var clock = Stopwatch.StartNew(); try { var response = await func(request); return(response); } catch (TException e) { var errorCode = getErrorCode?.Invoke(e) ?? HttpStatusCode.InternalServerError; var response = new TResponse { StatusCode = errorCode }; AlteredLog.Error(new { Name = name, request.RequestId, Response = new { StatusCode = (int)response.StatusCode, RequestDuration = clock.Elapsed.TotalMilliseconds, Exception = new { //e.StackTrace, StackTrace = new StackTrace(e).ToString(), e.Source, e.Message, Data = e.Data.ToDictionary().ToDictionary(kvp => $"{kvp.Key}", kvp => $"{kvp.Value}") } } }); return(response); } };