public async Task WrapAsync_should_return_action_result() { int maxRetries = 3; var filters = new ExceptionFilters(new[] { new ExceptionFilter(ex => ex is ArgumentNullException) }); var sut = new RetryPolicy(maxRetries, filters); Func <Task <bool> > action = () => Task.FromResult(true); var res = await sut.WrapAsync(action); res.Should().BeTrue(); }
public async Task WrapAsync_should_not_execute_action_when_max_retries_below_1() { var filters = new ExceptionFilters(Enumerable.Empty <ExceptionFilter>()); var sut = new RetryPolicy(0, filters); var hit = false; Func <Task <bool> > action = () => { hit = true; return(Task.FromResult(hit)); }; var result = await sut.WrapAsync(action); result.Should().BeFalse(); hit.Should().BeFalse(); }
/// <summary> /// Similar to <see cref="Filter(Action)" /> but this time, exceptions are not allowed to escape the action body and /// they are /// simply swallowed after being queued for reporting, with a small UI displayed to the user (if set so). Note that /// NBug can halt the execution with <c>Environment.Exit(0);</c> if you configured it to do so with /// <paramref name="continueExecution" /> /// parameter set to <see langword="false" />. You can simply use <c>Handle(true, () => { MyCodeHere(); })</c> /// </summary> /// <param name="continueExecution">Decides whether to exit application after handling the exception or continue execution.</param> /// <param name="body">Body of code to be executed.</param> public static void Handle(bool continueExecution, Action body) { ExceptionFilters.Filter( body, ex => { // Filtering the exception new BugReport().Report(ex, ExceptionThread.Main); return(true); // Yes proceed to handling the exception }, ex => { if (!continueExecution) { Environment.Exit(0); } }); }
protected void HandleException(Exception exception, CircuitState state) { if (ExceptionFilters.Any(filter => filter(exception))) { return; } if (ExcludedExceptions == null || !ExcludedExceptions.Contains(exception.GetType())) { state.ResetTime = DateTime.UtcNow.Add(Timeout); state.Increment(); if (state.Position == CircuitPosition.HalfOpen || state.CurrentIteration >= Threshold) { state.Position = CircuitPosition.Open; } Logger?.Invoke(exception.Message); } }
public async Task WrapAsync_should_throw_exception_immediately_if_not_handled() { int maxRetries = 3; var filters = new ExceptionFilters(new[] { new ExceptionFilter(ex => ex is ArgumentNullException) }); var sut = new RetryPolicy(maxRetries, filters); int count = 0; Func <Task <bool> > action = () => { count++; throw new ApplicationException(); }; await Assert.ThrowsAsync <ApplicationException>(async() => await sut.WrapAsync(action)); count.Should().Be(1); }
public async Task WrapAsync_should_run_delay_factory_on_exception() { var filters = new ExceptionFilters(Enumerable.Empty <ExceptionFilter>()); var hit = false; DelayFactory delayFactory = i => { hit = true; return(TimeSpan.Zero); }; var sut = new RetryPolicy(1, filters, delayFactory); await Assert.ThrowsAsync <ApplicationException>(async() => await sut.WrapAsync(() => { throw new ApplicationException(); })); hit.Should().BeTrue(); }
public async Task WrapAsync_should_throw_last_exception_when_retries_exhausted() { int maxRetries = 3; var filters = new ExceptionFilters(new[] { new ExceptionFilter(ex => ex is ApplicationException) }); var sut = new RetryPolicy(maxRetries, filters); int count = 0; Func <Task <bool> > action = () => { count++; throw new ApplicationException(count.ToString()); }; var ex = await Assert.ThrowsAsync <ApplicationException>(async() => await sut.WrapAsync(action)); ex.Message.Should().Be(count.ToString()); count.Should().Be(maxRetries); }
public async Task WrapAsync_should_call_on_exception_handler() { int maxRetries = 1; var filters = new ExceptionFilters(new[] { new ExceptionFilter(ex => ex is ApplicationException) }); var hit = false; OnExceptionHandler onException = ctx => { hit = true; return(Task.CompletedTask); }; var sut = new RetryPolicy(maxRetries, filters, null, onException); Func <Task <bool> > action = () => throw new ApplicationException(); await Assert.ThrowsAsync <ApplicationException>(async() => await sut.WrapAsync(action)); hit.Should().BeTrue(); }
public async Task WrapAsync_should_run_OnException_handler() { var filters = new ExceptionFilters(Enumerable.Empty <ExceptionFilter>()); DelayFactory delayFactory = i => TimeSpan.Zero; var hit = false; OnExceptionHandler onException = ctx => { hit = true; return(Task.CompletedTask); }; var sut = new RetryPolicy(1, filters, delayFactory, onException); await Assert.ThrowsAsync <ApplicationException>(async() => await sut.WrapAsync(() => { throw new ApplicationException(); })); hit.Should().BeTrue(); }
/// <summary> /// This function acts as an exception filter for any exception that is raised from within the action body (you can see /// MSDN subject "Exception Filters" to get more info on the subject). As the name implies, exceptions raised from /// within /// the action block is simply filtered to be sent as an error report, and never actually caught or handled. Filters /// all /// the exceptions inside the action body and queues an error report. Note that the exceptions are not actually /// handled, /// but filtered, so if the exception is left unhandled in an upper block, it will crash the application. This is very /// useful for situations where you need to log exceptions inside a code block and get a good minidump of the /// exception. /// Use the <see cref="Handle(bool,Action)" /> method to actually handle the exception and show an exception dialog to /// the /// user and shut down the application gracefully (if set so). You can simply use /// <c>Filter(() => { MyCodeHere(); })</c> /// </summary> /// <param name="body">Body of code to be executed.</param> public static void Filter(Action body) { ExceptionFilters.Filter(body, ex => new BugReport().Report(ex, ExceptionThread.Main)); }