You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The retry wrapper swallows all exceptions and returns a new default response instance, which can hide failures and make downstream logic treat failed calls as successful (especially if callers don’t validate the returned object). Consider returning an ErrorOr/Result type, rethrowing after logging, or at least allowing callers to opt-in to “return default on failure”.
publicstaticasyncTask<TResponse>InvokeWithRetryAsync<TResponse>(thisIMessageBusmessageBus,objectrequest,ILogger?logger=null,intretryAttempts=1,CancellationTokencancellationToken=default)whereTResponse:new(){varretryPolicy=Policy.Handle<Exception>().WaitAndRetryAsync(retryAttempts, retryAttempt =>TimeSpan.FromSeconds(Math.Pow(2,retryAttempt)));try{returnawaitretryPolicy.ExecuteAsync(async()=>awaitmessageBus.InvokeAsync<TResponse>(request,cancellationToken));}catch(Exceptione){if(loggeris not null)logger.LogError(e,"Error occurred while sending request: {Request}",request);elseConsole.WriteLine($"Error occurred while sending request: {request}");returnnewTResponse();}
Elapsed time is derived from TimeSpan.Milliseconds, which is only the milliseconds component (0-999) and not total duration. This will under-report requests taking longer than a second; use TotalMilliseconds (and an appropriate numeric type) to log accurate timings.
The handler no longer catches exceptions around agent chat invocation, so transient provider/network failures can now abort the handler entirely rather than producing a controlled retry/error result. Also, keyed DI lookup uses an upper-cased provider name; ensure service registrations use the same key normalization to avoid missing-service failures at runtime.
Stopwatch.GetElapsedTime(...).Milliseconds returns only the millisecond component (0-999), not the total duration, which will under-report timings. Use TotalMilliseconds and cast/round to keep accurate performance logs.
Why: Using Stopwatch.GetElapsedTime(...).Milliseconds only logs the milliseconds component (0-999) rather than total elapsed time, so timings will be incorrect. Switching to TotalMilliseconds makes the performance logging accurate with low risk.
Medium
Don't swallow invocation failures
Returning new TResponse() on failure silently hides errors and can make downstream logic behave as if a request succeeded. Log and rethrow so callers can handle the failure properly, and make retries honor the provided cancellationToken.
public static async Task<TResponse> InvokeWithRetryAsync<TResponse>(this IMessageBus messageBus,
object request,
ILogger? logger = null,
int retryAttempts = 1,
CancellationToken cancellationToken = default)
- where TResponse : new()
{
var retryPolicy = Policy.Handle<Exception>()
.WaitAndRetryAsync(retryAttempts, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));
+
try
{
- return await retryPolicy.ExecuteAsync(async () =>- await messageBus.InvokeAsync<TResponse>(request, cancellationToken));+ return await retryPolicy.ExecuteAsync(+ ct => messageBus.InvokeAsync<TResponse>(request, ct),+ cancellationToken);
}
catch (Exception e)
{
if (logger is not null)
logger.LogError(e, "Error occurred while sending request: {Request}", request);
else
Console.WriteLine($"Error occurred while sending request: {request}");
- return new TResponse();+ throw;
}
}
Suggestion importance[1-10]: 6
__
Why: Returning new TResponse() on exceptions can mask failures and lead callers to treat an errored invocation as a success; rethrowing makes failures explicit and easier to handle correctly. Updating Polly execution to honor the provided cancellationToken is also a real improvement.
Low
Guard provider key normalization
request.ProviderName can be null/empty (e.g., user input), which would throw when calling ToUpperInvariant(). Normalize safely by falling back to a default provider name before transforming the key.
Why: While request.ProviderName is declared as non-nullable and has a default, it can still be null at runtime in some edge cases, and normalizing/falling back could prevent a crash. However, this is mostly defensive and may hide invalid configuration/input rather than surfacing it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.