Snippset

Snipps

...see more

Testing HttpClient setup is a task many teams underestimate until something breaks in production. Modern .NET applications rely heavily on HttpClientFactory to add features such as retries, logging, authentication, or caching. These behaviors are implemented through message handlers that form a pipeline around every outgoing request.

If one handler is missing or misordered, the entire behavior changes—sometimes silently. A retry handler that never runs or a logging handler that is skipped can lead to confusing and costly issues. That’s why verifying the correct handlers are attached during application startup is essential.

However, developers quickly discover that it is not straightforward to test this. The built-in HttpClient does not expose its handler chain publicly, and typical unit-testing approaches cannot reveal what the factory actually constructs.

This Snipp explains the entire picture:
• the problem developers face when trying to validate HttpClient pipelines
• the cause, which is rooted in .NET’s internal design
• the resolution, with a practical reflection-based method to inspect handlers exactly as the runtime creates them

Following these Snipps, you will be able to reliably confirm that your handlers—such as retry and logging—are attached and working as intended.

...see more

If you've ever thought about trying Linux but felt overwhelmed by technical jargon or complex setup, Linux Mint might be exactly what you’re looking for. Designed for everyday users, it offers a clean and familiar interface, quick setup, and a focus on stability and ease of use.

Linux Mint is based on Ubuntu, one of the most widely used Linux distributions. This means you benefit from a huge software ecosystem, long-term support, and a strong community — without needing to dive deep into command-line tools unless you want to.

Why Linux Mint?

  • Easy to learn: The desktop layout feels familiar to users coming from Windows or macOS.
  • Reliable and secure: Regular updates help keep your system fast and safe.
  • Works on older hardware: A great option for breathing new life into older devices.
  • Comes ready to use: Essential software like a web browser, media player, and office suite are included from the start.

What makes it unique?

Linux Mint offers different desktop environments (such as Cinnamon, MATE, or Xfce), each balancing speed and visual appearance differently. You can choose what fits your hardware and personal preference best. The Software Manager also makes finding and installing applications as easy as in any modern app store.

Linux Mint is a practical starting point for anyone who wants a stable, user-friendly Linux experience — whether you're learning something new, switching operating systems entirely, or simply exploring alternatives.

...see more

We all like to believe we’d speak up against injustice — until the moment comes. The video presents a powerful real-life experiment: A professor unexpectedly orders a student, Alexis, to leave the lecture hall. No explanation. No misconduct. And no objections from her classmates.

Only after the door closes does the professor reveal the purpose of his shocking act. He asks the class why no one defended their peer. The uncomfortable truth: people stay silent when they aren’t personally affected.

The message hits hard — laws and justice aren’t self-sustaining. They rely on individuals willing to stand up for what’s right. If we ignore injustice simply because it doesn’t target us, we risk facing it ourselves with no one left to defend us.

This short demonstration challenges us to reflect on our own behavior:

  • Would we have spoken up?
  • What holds us back — fear, indifference, or convenience?
  • How can we develop the courage to act before it’s too late?

Justice needs voices. Silence only protects the unjust.

Video: One of The Greatest Lectures in The World. - GROWTH™ - YouTube

...see more

To test HttpClient handlers effectively, you need to inspect the internal handler chain that .NET builds at runtime. Since this chain is stored in a private field, reflection is the only reliable method to access it. The approach is safe, does not modify production code, and gives you full visibility into the pipeline.

The process begins by resolving your service from the DI container. If your service stores the HttpClient in a protected field, you can access it using reflection:

var field = typeof(MyClient)
    .GetField("_httpClient", BindingFlags.Instance | BindingFlags.NonPublic);

var httpClient = (HttpClient)field.GetValue(serviceInstance);

Next, retrieve the private _handler field from HttpMessageInvoker:

var handlerField = typeof(HttpMessageInvoker)
    .GetField("_handler", BindingFlags.Instance | BindingFlags.NonPublic);

var current = handlerField.GetValue(httpClient);

Finally, walk through the entire handler chain:

var handlers = new List<DelegatingHandler>();

while (current is DelegatingHandler delegating)
{
    handlers.Add(delegating);
    current = delegating.InnerHandler;
}

With this list, you can assert the presence of your custom handlers:

Assert.Contains(handlers, h => h is HttpRetryHandler);
Assert.Contains(handlers, h => h is HttpLogHandler);

This gives your test real confidence that the HttpClient pipeline is constructed correctly—exactly as it will run in production.

...see more

Issue

Libraries often expose many raw exceptions, depending on how internal HTTP or retry logic is implemented. This forces library consumers to guess which exceptions to catch and creates unstable behavior.

Cause

Exception strategy is not treated as part of the library’s public contract. Internal exceptions leak out, and any change in handlers or retry logic changes what callers experience.

Resolution

Define a clear exception boundary:

  1. Internally
    Catch relevant exceptions (HttpRequestException, timeout exceptions, retry exceptions).

  2. Log them
    Use the unified logging method.

  3. Expose only a custom exception
    Throw a single exception type, such as ServiceClientException, at the public boundary.

Code Example

catch (Exception ex)
{
    LogServiceException(ex);
    throw new ServiceClientException("Service request failed.", ex);
}

This approach creates a predictable public API, hides implementation details, and ensures your library remains stable even as the internal HTTP pipeline evolves.

...see more

The main reason regular tests cannot inspect HttpClient handlers is simple: the pipeline is private. The HttpClient instance created by IHttpClientFactory stores its entire message-handler chain inside a non-public field named _handler on its base class HttpMessageInvoker.

This means:

  • there is no public property to read the handler list
  • DI registration only confirms setup, not actual construction
  • mocks cannot expose the real pipeline
  • even typed clients hide the underlying handler chain

So while Visual Studio’s debugger can show the handler sequence, your code cannot. This is why common testing approaches fail: they operate at the service level, not the internal pipeline level.

A service class typically stores a protected or private HttpClient instance:

 
protected readonly HttpClient _httpClient;

Even if your test resolves this service, the handler pipeline remains invisible.

To validate the runtime configuration—exactly as it will behave in production—you must inspect the pipeline directly. Since .NET does not expose it, the only practical method is to use reflection. The next Snipp explains how to implement this in a clean and repeatable way.

...see more

Issue

HTTP calls fail for many reasons: timeouts, throttling, network issues, or retry exhaustion. Logging only one exception type results in missing or inconsistent diagnostic information.

Cause

Most implementations log only HttpRequestException, ignoring other relevant exceptions like retry errors or cancellation events. Over time, this makes troubleshooting difficult and logs incomplete.

Resolution

Use a single unified logging method that handles all relevant exception types. Apply specific messages for each category while keeping the logic in one place.

private void LogServiceException(Exception ex)
{
    switch (ex)
    {
        case HttpRequestException httpEx:
            LogHttpRequestException(httpEx);
            break;

        case RetryException retryEx:
            _logger.LogError("Retry exhausted. Last status: {Status}. Exception: {Ex}",
                retryEx.StatusCode, retryEx);
            break;

        case TaskCanceledException:
            _logger.LogError("Request timed out. Exception: {Ex}", ex);
            break;

        case OperationCanceledException:
            _logger.LogError("Operation was cancelled. Exception: {Ex}", ex);
            break;

        default:
            _logger.LogError("Unexpected error occurred. Exception: {Ex}", ex);
            break;
    }
}

private void LogHttpRequestException(HttpRequestException ex)
{
    if (ex.StatusCode == HttpStatusCode.NotFound)
        _logger.LogError("Resource not found. Exception: {Ex}", ex);
    else if (ex.StatusCode == HttpStatusCode.TooManyRequests)
        _logger.LogError("Request throttled. Exception: {Ex}", ex);
    else
        _logger.LogError("HTTP request failed ({Status}). Exception: {Ex}",
            ex.StatusCode, ex);
}

Centralizing logic ensures consistent, clear, and maintainable logging across all error paths.

...see more

When configuring HttpClient using AddHttpClient(), developers often attach important features using message handlers. These handlers form a step-by-step pipeline that processes outgoing requests. Examples include retry logic, request logging, or authentication.

The problem appears when you want to test that the correct handlers are attached. It is common to write integration tests that resolve your service from the DI container, call methods, and inspect behavior. But this does not confirm whether the handler chain is correct.

A handler can silently fail to attach due to a typo, incorrect registration, or a missing service. You may have code like this:

services.AddHttpClient("ClientService")
    .AddHttpMessageHandler<HttpRetryHandler>()
    .AddHttpMessageHandler<HttpLogHandler>();

But you cannot verify from your test that the constructed pipeline includes these handlers. Even worse, Visual Studio can display the handler chain in the debugger, but this ability is not accessible through public APIs.

Without a direct way to look inside the pipeline, teams cannot automatically verify one of the most important parts of their application’s networking stack. The next Snipp explains why this limitation exists.

...see more

The easiest and safest fix is to validate configuration values before Azure services are registered. This prevents accidental fallback authentication and gives clear feedback if something is missing.

Here’s a clean version of the solution:

public static IServiceCollection AddAzureResourceGraphClient(
    this IServiceCollection services,
    IConfiguration config)
{
    var connectionString = config["Authentication:AzureServiceAuthConnectionString"];

    if (string.IsNullOrWhiteSpace(connectionString))
        throw new InvalidOperationException(
            "Missing 'Authentication:AzureServiceAuthConnectionString' configuration."
        );

    services.AddSingleton(_ => new AzureServiceTokenProvider(connectionString));
    return services;
}

This small addition gives you:

✔ Clear error messages
✔ Consistent behavior between environments
✔ No more unexpected Azure calls during tests
✔ Easier debugging for teammates

For larger apps, you can also use strongly typed configuration + validation (IOptions<T>), which helps keep settings organized and ensures nothing slips through the cracks.

With this guard in place, your integration tests stay clean, predictable, and Azure-free unless you want them to involve Azure.

...see more

Most Azure SDK components rely on configuration values to know how to authenticate. For example:

new AzureServiceTokenProvider(
    config["Authentication:AzureServiceAuthConnectionString"]
);
 

If this key is missing, the Azure SDK does not stop. Instead, it thinks:
“I’ll figure this out myself!”

And then it tries fallback authentication options, such as:

  • Developer login credentials
  • Azure CLI authentication
  • Managed Identity lookups
  • Subscription scans

These attempts fail instantly inside a local test environment, leading to confusing “AccessDenied” messages.
The surprising part?
Your project may work fine during normal execution—but your API project or test project may simply be missing the same setting.

This tiny configuration mismatch means:

  • Unit tests succeed
  • API runs fine locally
  • Integration tests fail dramatically

Once you understand this, the solution becomes much clearer.

Add to Set
  • .NET
  • Agile
  • AI
  • ASP.NET Core
  • Azure
  • C#
  • Cloud Computing
  • CSS
  • EF Core
  • HTML
  • JavaScript
  • Microsoft Entra
  • PowerShell
  • Quotes
  • React
  • Security
  • Software Development
  • SQL
  • Technology
  • Testing
  • Visual Studio
  • Windows
Actions
 
Sets