Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,10 @@
<PackageReference Include="SIL.ReleaseTasks" Version="2.5.0" PrivateAssets="All" Condition="'$(Configuration)' != 'Debug'" />
</ItemGroup>

<!-- "Sentry" uses "Polyfill" and gives access to it's internals via "InternalsVisibleTo", but some Polyfills are in a separate namespace -->
<ItemGroup Condition="'$(MSBuildProjectName)' != 'Sentry' And $(MSBuildProjectName.StartsWith('Sentry.'))">
<!-- the latest TargetFramework requires no Polyfills; "Sentry.Compiler.Extensions" has its own Polyfills; "Android" and "Cocoa" projects are referenced by "Sentry" -->
<Using Include="Polyfills" Condition="'$(TargetFramework)' != $(LatestTfm) And $(MSBuildProjectName) != 'Sentry.Compiler.Extensions' And $(MSBuildProjectName) != 'Sentry.Android.AssemblyReader' And $(MSBuildProjectName) != 'Sentry.Bindings.Android' And $(MSBuildProjectName) != 'Sentry.Bindings.Cocoa'" />
</ItemGroup>

Copy link
Copy Markdown
Member Author

@Flash0ver Flash0ver Mar 4, 2026

Choose a reason for hiding this comment

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

note: this (and see also test/Directory.Build.props) is required

because some of the Polyfills have been moved into the Polyfills namespace.

This needs to be conditional,
because Sentry, to which Polyfill is emitting the Polyfills to as internal types,
does not give access of it's internals to every project in the src (and test) directory.

Alternatively,
we could add the global using (<Using Include="Polyfills" />) to every project that needs it,
but I found that to be quite a lot of additions, and new projects don't have them then per default,
so I suggest here to do it in a more central place.

</Project>
13 changes: 12 additions & 1 deletion src/Sentry.Analyzers/Sentry.Analyzers.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,19 @@
https://github.com/SimonCropp/Polyfill
-->
<ItemGroup>
<PackageReference Include="Polyfill" Version="1.32.0" PrivateAssets="all" />
<PackageReference Include="Polyfill" Version="9.8.1" PrivateAssets="all" />
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

issue: Test failure

  • Project: Sentry.Tests
  • Test: Sentry.Tests.SentrySdkCrashTests.CauseCrashInSeparateProcess
  • TFM: net48
Unhandled Exception: System.IO.FileLoadException: Could not load file or assembly 'System.Memory, Version=4.0.1.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
   at Sentry.SentrySdk.CauseCrash(CrashType crashType)
   at Sentry.Testing.CrashableApp.Program.Main(String[] args) in D:\GitHub\sentry-dotnet\test\Sentry.Testing.CrashableApp\Program.cs:line 9

</ItemGroup>
<!-- We currently don't require Polyfills for System.Memory. Ensure the feature is disabled and suppress the MSBuild Warning from Polyfill. -->
<Target Name="BeforePreparePolyfill" BeforeTargets="PreparePolyfill">
<PropertyGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PolyfillNoWarnIncorrectVersion>true</PolyfillNoWarnIncorrectVersion>
</PropertyGroup>
</Target>
<Target Name="AfterPreparePolyfill" AfterTargets="PreparePolyfill" DependsOnTargets="PreparePolyfill">
<PropertyGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<DefineConstants>$([System.String]::Copy('$(DefineConstants)').Replace('FeatureMemory','').Replace(';;',';'))</DefineConstants>
</PropertyGroup>
</Target>

<ItemGroup>
<Using Remove="System.Text.Json" />
Expand Down
8 changes: 2 additions & 6 deletions src/Sentry/Internal/Extensions/CollectionsExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,14 @@ public static IEnumerable<KeyValuePair<TKey, TValue>> WhereNotNullValue<TKey, TV
}
}
}

public static IEnumerable<KeyValuePair<TKey, TValue>> Append<TKey, TValue>(
this IEnumerable<KeyValuePair<TKey, TValue>> source, TKey key, TValue value) =>
source.Append(new KeyValuePair<TKey, TValue>(key, value));

public static IReadOnlyList<T> AsReadOnly<T>(this IList<T> list) =>
list as IReadOnlyList<T> ?? new ReadOnlyCollection<T>(list);

#if !NET7_0_OR_GREATER
public static IReadOnlyDictionary<TKey, TValue> AsReadOnly<TKey, TValue>(this IDictionary<TKey, TValue> dictionary)
where TKey : notnull =>
new ReadOnlyDictionary<TKey, TValue>(dictionary);
#endif

Comment on lines -78 to -83
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

note: now included via Polyfill

public static IEnumerable<T> ExceptNulls<T>(this IEnumerable<T?> source) =>
source.Where(x => x != null).Select(x => x!);

Expand Down
13 changes: 12 additions & 1 deletion src/Sentry/Sentry.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,13 @@
https://github.com/SimonCropp/Polyfill
-->
<ItemGroup>
<PackageReference Include="Polyfill" Version="1.32.0" PrivateAssets="all" />
<PackageReference Include="Polyfill" Version="9.8.1" PrivateAssets="all" />
</ItemGroup>
<PropertyGroup>
<PolyStringInterpolation>true</PolyStringInterpolation>
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

note: PolyStringInterpolation emits a DefaultInterpolatedStringHandler, which the compiler considers for String Interpolation when not all holes are strings. This is more efficient than String.Format. But makes our netstandard2.1, netstandard2.0 and net462 targets, and with that the entire Sentry NuGet package, a bit larger:

See Assembly size impact

<DefineConstants Condition="'$(TargetFramework)' == 'netstandard2.0'">$(DefineConstants);FeatureHttp</DefineConstants>
<DefineConstants Condition="'$(TargetFramework)' == 'netstandard2.1'">$(DefineConstants);FeatureHttp</DefineConstants>
</PropertyGroup>

<!--
On .NET Framework, we need a package reference to System.Runtime.InteropServices.RuntimeInformation.
Expand All @@ -86,6 +91,12 @@
<PackageReference Include="System.Text.Json" Version="8.0.5" />
</ItemGroup>

<!-- Due to Polyfill, System.Memory needs to be a top-level dependency, otherwise app start may fail with:
System.IO.FileLoadException: Could not load file or assembly 'System.Memory' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. -->
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0' Or '$(TargetFramework)' == 'net462'">
<PackageReference Include="System.Memory" Version="4.6.3" />
</ItemGroup>

Comment on lines +94 to +99
Copy link
Copy Markdown
Member Author

@Flash0ver Flash0ver Mar 9, 2026

Choose a reason for hiding this comment

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

thought: This could be an issue!

related to https://github.com/getsentry/sentry-dotnet/pull/4879/changes#r2895293577
(Sentry.Tests.SentrySdkCrashTests.CauseCrashInSeparateProcess(CrashType) is a great test !!!)

I wonder if this may be considered a breaking change,
and if we should hold off on this upgrade for our next Major (Sentry v7 supporting .NET 11).

But this would mean to similarly hold off on follow-up changes like

(although, actually, we could simply write our own ANE.ThrowIfNull(object?) internal static extension method for now, and later replace it with the Polyfill-variant)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yeah I'd say we avoid adding dependencies to the core package... especially when it's just for polyfills which we don't need for any functional reason (they're just to make the code slightly more attractive to read really).

What's the most recent version of Polyfill that doesn't require we change any dependencies for SDK users? We could try bumping to that instead maybe?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Great idea!
Unfortunately, the Polyfill changelog is quite ... unavailable.
Will "binary search" on a Windows machine.

Copy link
Copy Markdown
Member Author

@Flash0ver Flash0ver Mar 11, 2026

Choose a reason for hiding this comment

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

No changelog / release notes == no fun ☹️.

1.34.0 includes this - for our scenario - breaking change.

Closing this PR.
Instead opened PR #5007 to update to the latest non-breaking version (1.33.2).
Opened issue #5006 to be considered for our next Major release.

<!--
Include Sentry's custom targets file in the nuget package.
This file contains targets that are invoked during the end-user's build.
Expand Down
6 changes: 6 additions & 0 deletions test/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,10 @@
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" />
</ItemGroup>

<!-- "Sentry" uses "Polyfill" and gives access to it's internals via "InternalsVisibleTo", but some Polyfills are in a separate namespace -->
<ItemGroup Condition="'$(MSBuildProjectName)' != 'Sentry' And $(MSBuildProjectName.StartsWith('Sentry.'))">
<!-- the latest TargetFramework requires no Polyfills -->
<Using Include="Polyfills" Condition="'$(TargetFramework)' != $(LatestTfm)" />
</ItemGroup>

</Project>