DEV Community

Cover image for C# Tip: Exception handling with WHEN clause
Davide Bellone
Davide Bellone

Posted on • Originally published at code4it.dev

C# Tip: Exception handling with WHEN clause

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();
    }
}
Enter fullscreen mode Exit fullscreen mode

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");
} 
Enter fullscreen mode Exit fullscreen mode

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");
}
Enter fullscreen mode Exit fullscreen mode

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");
}
Enter fullscreen mode Exit fullscreen mode

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? 😉

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

Happy coding!

🐧

Discussion (0)