Skip to content

Conversation

jamescrosswell
Copy link
Collaborator

@jamescrosswell jamescrosswell commented Sep 19, 2025

Resolves #4480:


Note

Skip emitting sentry.message.template in structured logs without parameters; adds coverage and updates changelog.

  • Structured Logs:
    • Update src/Sentry/SentryLog.cs to only write attributes.sentry.message.template when Template is set and Parameters has length > 0.
  • Tests:
    • Add WriteTo_NoParameters_NoTemplate theory in test/Sentry.Tests/SentryLogTests.cs to assert presence/absence of sentry.message.template based on parameters.
  • Docs/Changelog:
    • Update CHANGELOG.md under Fixes to note templates aren’t sent for logs without parameters.

Written by Cursor Bugbot for commit faad68a. This will update automatically on new commits. Configure here.

Copy link

codecov bot commented Sep 19, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 73.48%. Comparing base (2dc1551) to head (faad68a).
⚠️ Report is 5 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4544      +/-   ##
==========================================
+ Coverage   73.33%   73.48%   +0.14%     
==========================================
  Files         479      482       +3     
  Lines       17509    17679     +170     
  Branches     3445     3495      +50     
==========================================
+ Hits        12840    12991     +151     
- Misses       3789     3798       +9     
- Partials      880      890      +10     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@jamescrosswell jamescrosswell marked this pull request as ready for review September 19, 2025 07:48
if (Template is not null)
// the SDK MUST NOT attach a sentry.message.template attribute if there are no parameters
// https://develop.sentry.dev/sdk/telemetry/logs/#default-attributes
if (Template is not null && Parameters is { Length: > 0 })
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

potential issue: Accessing Length could throw NullReferenceException when default

Suggested change
if (Template is not null && Parameters is { Length: > 0 })
if (Template is not null && !Parameters.IsDefaultOrEmpty)

Admittedly, this is a bit pedantic. We currently have no flow setting the Parameters to default, but we technically could make a (semi-)related change in the future and then run into an NRE along the line.

ImmutableArray<KeyValuePair<string, object>> parameters = default;
_ = parameters.Length; // System.NullReferenceException: Object reference not set to an instance of an object.

The ImmutableArray<T>.Length property is accessing the underlying array directly, which is null when the struct ImmutableArray<T> is (explicitly/implicitly) default.
ImmutableArray<T>.IsEmpty has a similar behavior.

To be on the safe side, I suggest using ImmutableArray<T>.IsDefaultOrEmpty which ensures that this struct instance isn't default by checking whether the underlying array is null before accessing its Length.

Context:
I decided to use ImmutableArray<T> here, because we expose the SentryLog.Parameters publicly and to render this collection immutable through e.g. the user-defined SetBeforeSendLog(Func<SentryLog, SentryLog?>) delegate. It does have its usage quirks for the benefit of similar performance characteristics to using a mutable Array directly.

Copy link
Collaborator Author

@jamescrosswell jamescrosswell Sep 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this us guarded against. If the condition was Parameters is { } then it would ensure Parameters isn't null... and so Parameters is { Length: > 0 } ensures that it's not null and has more than one element right?

EDIT: Oh, I see... default != null

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah ... ImmutableArray`1 is a value type. But the underlying array is a reference type. And the Length property does not perform a null check on the underlying array, which actually is null should the ImmutableArray`1 be initialized to default.

jamescrosswell and others added 2 commits September 28, 2025 16:35
if (Template is not null)
// the SDK MUST NOT attach a sentry.message.template attribute if there are no parameters
// https://develop.sentry.dev/sdk/telemetry/logs/#default-attributes
if (Template is not null && Parameters is { Length: > 0 })
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Default ImmutableArray Length Access Throws Exception

The condition Parameters is { Length: > 0 } can throw an InvalidOperationException if Parameters is a default ImmutableArray<T>. Accessing the Length property on a default ImmutableArray causes this exception, which is inconsistent with how ImmutableArray is handled elsewhere.

Fix in Cursor Fix in Web

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Partially correct.
The get_Length property does indeed throw when Parameters is a default ImmutableArray<T>.
But it does not throw an InvalidOperationException, but a NullReferenceException!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Make sure the .NET SDK only sets sentry.message.template on logs if sentry.message.parameter values are also defined
3 participants