Code4IT

The place for .NET enthusiasts, Azure lovers, and backend developers

C# Tip: Exception handling with WHEN clause

2022-02-08 2 min read CSharp Tips
Just a second! 🫷
If you are here, it means that you are a software developer. So, you know that storage, networking, and domain management have a cost .

If you want to support this blog, please ensure that you have disabled the adblocker for this site. I configured Google AdSense to show as few ADS as possible - I don't want to bother you with lots of ads, but I still need to add some to pay for the resources for my site.

Thank you for your understanding.
- Davide

From C# 6 on, you can use the when keyword to specify a condition before handling an exception.

Consider this - pretty useless, I have to admit - type of exception:

public class RandomException : System.Exception
{
    public int Value { get; }
    public RandomException()
    {
        Value = (new Random()).Next();
    }
}

This exception type contains a Value property which is populated with a random value when the exception is thrown.

What if you want to print a different message depending on whether the Value property is odd or even?

You can do it this way:

try
{
    throw new RandomException();
}
catch (RandomException re)
{
    if(re.Value % 2 == 0)
        Console.WriteLine("Exception with even value");
    else
        Console.WriteLine("Exception with odd value");
}

But, well, you should keep your catch blocks as simple as possible.

That’s where the when keyword comes in handy.

CSharp when clause

You can use it to create two distinct catch blocks, each one of them handles their case in the cleanest way possible.

try
{
    throw new RandomException();
}
catch (RandomException re) when (re.Value % 2 == 0)
{
    Console.WriteLine("Exception with even value");
}
catch (RandomException re)
{
    Console.WriteLine("Exception with odd value");
}

You must use the when keyword in conjunction with a condition, which can also reference the current instance of the exception being caught. In fact, the condition references the Value property of the RandomException instance.

A real usage: HTTP response errors

Ok, that example with the random exception is a bit… useless?

Let’s see a real example: handling different HTTP status codes in case of failing HTTP calls.

In the following snippet, I call an endpoint that returns a specified status code (506, in my case).

try
{
    var endpoint = "https://mock.codes/506";
    var httpClient = new HttpClient();
    var response = await httpClient.GetAsync(endpoint);
    response.EnsureSuccessStatusCode();
}
catch (HttpRequestException ex) when (ex.StatusCode == (HttpStatusCode)506)
{
    Console.WriteLine("Handle 506: Variant also negotiates");
}
catch (HttpRequestException ex)
{
    Console.WriteLine("Handle another status code");
}

If the response is not a success, the response.EnsureSuccessStatusCode() throws an exception of type HttpRequestException. The thrown exception contains some info about the returned status code, which we can use to route the exception handling to the correct catch block using when (ex.StatusCode == (HttpStatusCode)506).

Quite interesting, uh? πŸ˜‰

This article first appeared on Code4IT

To read more, you can head to the official documentation, even though there’s not so much.

Happy coding!

🐧

About the author

Davide Bellone is a Principal Backend Developer with more than 10 years of professional experience with Microsoft platforms and frameworks.

He loves learning new things and sharing these learnings with others: that’s why he writes on this blog and is involved as speaker at tech conferences.

He's a Microsoft MVP πŸ†, conference speaker (here's his Sessionize Profile) and content creator on LinkedIn.