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; using System.Diagnostics.CodeAnalysis; [System.Diagnostics.StackTraceHidden] public static class Helpers { public static void ThrowIfNull([NotNull] object? argument, [CallerArgumentExpression("argument")] string paramName = null) { if (argument == null) { throw new ArgumentNullException(paramName); } } }
Code language: C# (cs)

Notes: 1) This is using the CallerArgumentExpression attribute (from .NET 6) to automatically get the passed in parameter name – just like what ArgumentNullException.ThrowIfNull() uses. 2) Updated 2022-08-26. A commenter pointed out this produces a Nullable analyzer warning in the calling code. Make it a nullable + use [NotNull] to take care of that (i.e. ‘[NotNull] object? argument’ instead of ‘object argument’)

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)

6 thoughts on “C# – Exclude exception throw helper methods from the stack trace”

  1. For methods like ThrowIfNull(employee), is there a way to tell the static analyzers that in subsequent statements, employee will not be null?

    Reply
    • Good question. So I’m assuming you’re referring to the Nullable feature and specifically warning CS8604 (‘x could be null’).

      To get rid of that warning in the calling code, update the null-checking method to use [NotNull]object? argument (instead of the non-nullable – object argument), like this:
      public static void ThrowIfNull([NotNull]object? argument, ….).

      This makes it so the analyzer knows that the object was null-checked and therefore won’t be null after this method is called.

      This is actually what the built-in ArgumentNullException.ThrowIfNull() has, and I totally missed it because I didn’t have the Nullable feature turned on at the time. I’ll go ahead and update the code example in the article with this change too.

      Reply
    • nm. I found the [System.Diagnostics.CodeAnalysis.NotNull] attribute

      Oops. You beat me to it. Thank you!

      (note from Mak – combined these two comments)

      Reply
  2. Hey Mak, Is this available in .net framework?
    I just add that attribute into my code(net472, VS2022), and it doesn’t work.

    Reply
    • Hey Joe,

      This attribute was added in .NET 6. So unfortunately, no, it’s not available in your .NET Framework version.

      Reply

Leave a Comment