Unreachable code and UnreachableException

UnreachableException - the new exception which should never be thrown

Home DailyDrop

Daily Knowledge Drop

The UnreachableException was introduced in .NET 7, which is used in situations when the application executes code thought to be unreachable. If this exception does occur, then there is an error in the flow or data of the application causing the, previous thought, unreachable code to be executed.


Unreachable code setup

Consider the follow example of example - we have an enum of OrderStatus:

public enum OrderStatus
{
    New = 0,
    Processing = 1,
    Fulfilled = 2,
    OutOnDelivery = 3,
    Delivered = 4
}

As well as a switch expression to convert the enum value to a string description :

string currentStatusText = currentStatus switch
{
    OrderStatus.New => "Order Placed",
    OrderStatus.Processing => "Processing Order",
    OrderStatus.Fulfilled => "Processing Order",
    OrderStatus.OutOnDelivery => "Order is out on delivery",
    OrderStatus.Delivered => "Order is delivered",
    _ => throw new UnreachableException($"OrderStatus enum " +
        $"value {currentStatus} invalid")
};

The UnreachableException is used if the code tries to convert an OrderStatus which does not exist to a string - in theory a situation which should never occur.

We also have a method to retrieve the order status, stored as an int, from the database:

public OrderStatus GetOrderStatusFromDatabase()
{
    // simulate getting the value from the database
    return (OrderStatus)2;
}

Executing unreachable code

If the database stores a valid OrderStatus int value, everything will execute as expected.

In this example, the database stores an OrderStatus value of 2:

// currentStatus is 2
OrderStatus currentStatus = GetOrderStatusFromDatabase();

var currentStatusText = currentStatus switch
{
    OrderStatus.New => "Order Placed",
    OrderStatus.Processing => "Processing Order",
    OrderStatus.Fulfilled => "Processing Order",
    OrderStatus.OutOnDelivery => "Order is out on delivery",
    OrderStatus.Delivered => "Order is delivered",
    _ => throw new UnreachableException()
};

Console.WriteLine($"Order status: {currentStatusText}");

The output is:

Order: Processing Order

However, if the OrderStatus was manually, incorrectly updated to be 5 in the database - this is a situation which should never happen, but in reality it could:

// currentStatus is 5
OrderStatus currentStatus = GetOrderStatusFromDatabase();

string currentStatusText = currentStatus switch
{
    OrderStatus.New => "Order Placed",
    OrderStatus.Processing => "Processing Order",
    OrderStatus.Fulfilled => "Processing Order",
    OrderStatus.OutOnDelivery => "Order is out on delivery",
    OrderStatus.Delivered => "Order is delivered",
    _ => throw new UnreachableException($"OrderStatus enum " +
        $"value {currentStatus} invalid")
};

Console.WriteLine($"Order status: {currentStatusText}");

The C# code allows the currentStatus variable to be set to a value of 5, an enum value which doesn't exist - and only when it comes time to convert to a string (in the switch expression), will there be no match to any of the options and the UnreachableException be thrown.

Monitoring tools or logs can now be checked for the presence of UnreachableException and if such an exception occurs, something has gone wrong.


Notes

A useful tool at a developers disposal to assist in tracking down completely unexpected issues which may arise - but a tool which should hopefully never actually be reached to be used!


References

The new .NET Exception that should NEVER be thrown

Daily Drop 218: 07-12-2022

At the start of 2022 I set myself the goal of learning one new coding related piece of knowledge a day.
It could be anything - some.NET / C# functionality I wasn't aware of, a design practice, a cool new coding technique, or just something I find interesting. It could be something I knew at one point but had forgotten, or something completely new, which I may or may never actually use.

The Daily Drop is a record of these pieces of knowledge - writing about and summarizing them helps re-enforce the information for myself, as well as potentially helps others learn something new as well.
c# .net exception .net7 unreachable