Rethrowing your exceptions wrong in .NET could erase your stacktrace
Tags: dotnet, csharp
Published: 2020-12-04 21:15:22

---
title: Rethrowing your exceptions wrong in .NET could erase your stacktrace
published: true
date: 2020-12-04 00:00:00 UTC
tags: dotnet, csharp
canonical_url: https://swimburger.net/blog/dotnet/rethrowing-your-exceptions-wrong-in-dotnet-could-erase-your-stacktrace
---

You may be erasing your stacktrace if you are catching and rethrowing exceptions the wrong way. This could make debugging a nightmare because you don't know where the exception was originally thrown.   
You are erasing parts of the stacktrace if you are catching and rethrowing exceptions like this:

```csharp
try
{
    DoWork();
}
catch (Exception ex)
{
    throw ex;
}

```

If you catch the rethrown exception and print out the stacktrace, you will notice that there's no mention of the `DoWork` method where the exception was originally thrown.

```
System.Exception: Exception of type 'System.Exception' was thrown.
    at CatchRethrow.Program.IncorrectCatchAndReThrow() in /home/azureuser/CatchRethrow/Program.cs:line 50
    at CatchRethrow.Program.Main(String[] args) in /home/azureuser/CatchRethrow/Program.cs:line 22
```

That's because it was overwritten when the exception was rethrown.  
The correct syntax is to use `throw;` instead of `throw ex;`:

```csharp
try
{
    DoWork();
}
catch (Exception ex)
{
    throw;
}
```

If you catch the rethrown exception now and print out the stacktrace, the `DoWork` method is printed as part of the stacktrace: 

```
System.Exception: Exception of type 'System.Exception' was thrown.
    at CatchRethrow.Program.DoWork() in /home/azureuser/CatchRethrow/Program.cs:line 56
    at CatchRethrow.Program.CorrectCatchAndThrow() in /home/azureuser/CatchRethrow/Program.cs:line 34
    at CatchRethrow.Program.Main(String[] args) in /home/azureuser/CatchRethrow/Program.cs:line 12
```

Luckily, there's a code analysis rule "[CA2200: Rethrow to preserve stack details](https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca2200)" that will warn you about this.   
Here's the full sample of the code used to demonstrate the issue above:

```csharp
using System;

class Program
{
    static void Main(string[] args)
    {
        // correct catch/throw
        try
        {
            CorrectCatchAndThrow();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
            /*
            System.Exception: Exception of type 'System.Exception' was thrown.
                at CatchRethrow.Program.DoWork() in /home/azureuser/CatchRethrow/Program.cs:line 56
                at CatchRethrow.Program.CorrectCatchAndThrow() in /home/azureuser/CatchRethrow/Program.cs:line 34
                at CatchRethrow.Program.Main(String[] args) in /home/azureuser/CatchRethrow/Program.cs:line 12
            */
        }

        // incorrect catch/throw
        try
        {
            IncorrectCatchAndReThrow();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
            /*
            System.Exception: Exception of type 'System.Exception' was thrown.
                at CatchRethrow.Program.IncorrectCatchAndReThrow() in /home/azureuser/CatchRethrow/Program.cs:line 50
                at CatchRethrow.Program.Main(String[] args) in /home/azureuser/CatchRethrow/Program.cs:line 22
            */
        }
    }

    static void CorrectCatchAndThrow()
    {
        try
        {
            DoWork();
        }
        catch (Exception ex)
        {
            throw;
        }
    }

    static void IncorrectCatchAndReThrow()
    {
        try
        {
            DoWork();
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

    static void DoWork()
    {
        throw new Exception();
    }
}
```