@@ -75,7 +75,7 @@ public async Task ExecuteTaskAsync_SetsElapsedTime_OnSuccess()
7575
7676 await _handler . ExecuteTaskAsync ( context , isDue : false ) ;
7777
78- context . ElapsedTime . Should ( ) . BeGreaterOrEqualTo ( 0 ) ;
78+ context . ElapsedTime . Should ( ) . BeGreaterThanOrEqualTo ( 0 ) ;
7979 }
8080
8181 [ Fact ]
@@ -136,6 +136,52 @@ await exceptionHandler.Received(1).HandleExceptionAsync(
136136 Arg . Is ( context . Type ) ) ;
137137 }
138138
139+ [ Fact ]
140+ public async Task ExecuteTaskAsync_CallsExceptionHandler_ForEachFailedAttempt ( )
141+ {
142+ var exceptionHandler = Substitute . For < ITickerExceptionHandler > ( ) ;
143+ var services = new ServiceCollection ( ) ;
144+ services . AddSingleton ( _internalManager ) ;
145+ services . AddSingleton ( _instrumentation ) ;
146+ services . AddSingleton ( exceptionHandler ) ;
147+ var sp = services . BuildServiceProvider ( ) ;
148+ var handler = new TickerExecutionTaskHandler ( sp , _clock , _instrumentation , _internalManager ) ;
149+
150+ var context = CreateContext ( ct : ( _ , _ , _ ) => throw new InvalidOperationException ( "boom" ) ) ;
151+ context . Retries = 2 ;
152+ context . RetryIntervals = [ 0 , 0 ] ;
153+
154+ await handler . ExecuteTaskAsync ( context , isDue : false ) ;
155+
156+ await exceptionHandler . Received ( 3 ) . HandleExceptionAsync (
157+ Arg . Any < Exception > ( ) ,
158+ Arg . Is ( context . TickerId ) ,
159+ Arg . Is ( context . Type ) ) ;
160+ }
161+
162+ [ Fact ]
163+ public async Task ExecuteTaskAsync_UpdatesExceptionDetails_OnFailedAttemptBeforeRetriesComplete ( )
164+ {
165+ var context = CreateContext ( ct : ( _ , _ , _ ) => throw new InvalidOperationException ( "boom" ) ) ;
166+ context . Retries = 1 ;
167+ context . RetryIntervals = [ 0 ] ;
168+ var observedUpdates = new List < ( TickerStatus Status , string ExceptionDetails ) > ( ) ;
169+
170+ _internalManager
171+ . When ( x => x . UpdateTickerAsync ( Arg . Any < InternalFunctionContext > ( ) , Arg . Any < CancellationToken > ( ) ) )
172+ . Do ( callInfo =>
173+ {
174+ var ctx = callInfo . Arg < InternalFunctionContext > ( ) ;
175+ observedUpdates . Add ( ( ctx . Status , ctx . ExceptionDetails ) ) ;
176+ } ) ;
177+
178+ await _handler . ExecuteTaskAsync ( context , isDue : false ) ;
179+
180+ observedUpdates . Should ( ) . Contain ( x =>
181+ x . Status == TickerStatus . InProgress &&
182+ ! string . IsNullOrWhiteSpace ( x . ExceptionDetails ) ) ;
183+ }
184+
139185 #endregion
140186
141187 #region Cancellation Path
0 commit comments