C# – Exclude exception throw helper methods from the stack trace

When you want to exclude a method from showing up in the stack trace, you can apply the StackTraceHidden attribute to the method:

[System.Diagnostics.StackTraceHidden] public static void Throw() { //check conditions and throw }
Code language: C# (cs)

Note: This attribute was added in .NET 6.

You can apply StackTraceHidden to a class to hide all of its methods from the stack trace:

[System.Diagnostics.StackTraceHidden] public static class Helpers { //lots of exception thrower helper methods }
Code language: C# (cs)

One very useful application of the StackTraceHidden attribute is excluding exception throw helper methods from the stack trace. To see why this is useful, let’s start by looking at manually written if-then-throw statements:

void Process(Employee employee) { if (employee == null) { throw new ArgumentNullException(nameof(employee)); } if (string.IsNullOrEmpty(employee.FirstName)) { throw new ArgumentNullException(nameof(employee.FirstName)); } //process employee }
Code language: C# (cs)

Devs usually don’t like repeatedly typing these redundant if-then-throw statements, so they end up writing throw helper methods, or using third-party / built-in methods. Here’s an example of using the built-in ArgumentNullException.ThrowIfNull() helper method:

void Process(Employee employee) { ArgumentNullException.ThrowIfNull(employee); ArgumentNullException.ThrowIfNull(employee.FirstName); //process employees }
Code language: C# (cs)

Note: ArgumentNullException.ThrowIfNull() was added in .NET 6.

Throw helper methods solve one problem (redundant if-then-throw statements), but introduce another problem: stack trace pollution. When you throw an exception, the stack trace includes all methods in the call chain, including the throw helper method (and whatever it calls) right at the top:

System.ArgumentNullException: Value cannot be null. (Parameter 'employee.FirstName') at System.ArgumentNullException.Throw(String paramName) at System.ArgumentNullException.ThrowIfNull(Object argument, String paramName) at Program.Process(Employee employee) in D:\Program.cs:line 19
Code language: plaintext (plaintext)

The throw helper method is irrelevant information. It’s just noise that pollutes the stack trace message, making it more difficult to interpret, especially when you’re reading it in a log file.

This is where the StackTraceHidden attribute comes in. You can use it to hide your own throw helper methods from the stack trace.

using System.Runtime.CompilerServices; [System.Diagnostics.StackTraceHidden] public static class Helpers { public static void ThrowIfNull(object argument, [CallerArgumentExpression("argument")] string paramName = null) { if (argument == null) { throw new ArgumentNullException(paramName); } } }
Code language: C# (cs)

Note: This is using the CallerArgumentExpression attribute (from .NET 6) to automatically get the passed in parameter name – just like what ArgumentNullException.ThrowIfNull() uses.

Here’s an example of calling this throw helper method:

void Process(Employee employee) { Helpers.ThrowIfNull(employee); Helpers.ThrowIfNull(employee.FirstName); //process employees }
Code language: C# (cs)

Here’s the stack trace. Notice it doesn’t have the Helpers.ThrowIfNull() call in it:

System.ArgumentNullException: Value cannot be null. (Parameter 'employee.FirstName') at Program.Process(Employee employee) in D:\Program.cs:line 19
Code language: plaintext (plaintext)

Leave a Comment