From 1eac0fae74c110a350a7af1768a1bbc47b7670ea Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Mar 2026 03:36:04 +0000 Subject: [PATCH 01/11] Initial plan From a34cd7ae15e91054c50bb2a572d4828db5062cd8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Mar 2026 03:51:01 +0000 Subject: [PATCH 02/11] ref: Use ArgumentNullException.ThrowIfNull helpers, update Polyfill to 9.8.1 Co-authored-by: jamescrosswell <728212+jamescrosswell@users.noreply.github.com> --- src/Directory.Build.props | 6 ++++ src/Sentry.Analyzers/Sentry.Analyzers.csproj | 13 ++++++++- .../SystemWebRequestEventProcessor.cs | 6 ++-- .../ProtobufRequestExtractionDispatcher.cs | 9 ++++-- .../SentryGrpcInterceptor.cs | 3 +- .../SentryAspNetCoreBuilder.cs | 3 +- src/Sentry.AspNetCore/SentryMiddleware.cs | 3 +- .../DelegateLogEntryFilter.cs | 5 +++- .../RequestBodyExtractionDispatcher.cs | 9 ++++-- .../Extensions/CollectionsExtensions.cs | 6 ---- .../Http/DefaultSentryHttpClientFactory.cs | 5 +--- src/Sentry/Internal/Http/RetryAfterHandler.cs | 5 +++- src/Sentry/Internal/Polyfills.cs | 28 ------------------- src/Sentry/Internal/SdkComposer.cs | 3 +- src/Sentry/Sentry.csproj | 7 ++++- src/Sentry/SentryClient.cs | 3 +- src/Sentry/SentryOptions.cs | 13 +++------ test/Directory.Build.props | 6 ++++ 18 files changed, 69 insertions(+), 64 deletions(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index e3e1feb526..2bf3cc7ef0 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -60,4 +60,10 @@ + + + + + + diff --git a/src/Sentry.Analyzers/Sentry.Analyzers.csproj b/src/Sentry.Analyzers/Sentry.Analyzers.csproj index 223a1434f8..066247e82c 100644 --- a/src/Sentry.Analyzers/Sentry.Analyzers.csproj +++ b/src/Sentry.Analyzers/Sentry.Analyzers.csproj @@ -24,8 +24,19 @@ https://github.com/SimonCropp/Polyfill --> - + + + + + true + + + + + $([System.String]::Copy('$(DefineConstants)').Replace('FeatureMemory','').Replace(';;',';')) + + diff --git a/src/Sentry.AspNet/Internal/SystemWebRequestEventProcessor.cs b/src/Sentry.AspNet/Internal/SystemWebRequestEventProcessor.cs index 960a131004..0c00a93e86 100644 --- a/src/Sentry.AspNet/Internal/SystemWebRequestEventProcessor.cs +++ b/src/Sentry.AspNet/Internal/SystemWebRequestEventProcessor.cs @@ -14,8 +14,10 @@ internal class SystemWebRequestEventProcessor : ISentryEventProcessor public SystemWebRequestEventProcessor(IRequestPayloadExtractor payloadExtractor, SentryOptions options) { - _options = options ?? throw new ArgumentNullException(nameof(options)); - PayloadExtractor = payloadExtractor ?? throw new ArgumentNullException(nameof(payloadExtractor)); + ArgumentNullException.ThrowIfNull(options); + _options = options; + ArgumentNullException.ThrowIfNull(payloadExtractor); + PayloadExtractor = payloadExtractor; } public SentryEvent? Process(SentryEvent? @event) diff --git a/src/Sentry.AspNetCore.Grpc/ProtobufRequestExtractionDispatcher.cs b/src/Sentry.AspNetCore.Grpc/ProtobufRequestExtractionDispatcher.cs index 39aa1c678f..10f7d713f0 100644 --- a/src/Sentry.AspNetCore.Grpc/ProtobufRequestExtractionDispatcher.cs +++ b/src/Sentry.AspNetCore.Grpc/ProtobufRequestExtractionDispatcher.cs @@ -23,9 +23,12 @@ public class ProtobufRequestExtractionDispatcher : IProtobufRequestPayloadExtrac public ProtobufRequestExtractionDispatcher(IEnumerable extractors, SentryOptions options, Func sizeSwitch) { - Extractors = extractors ?? throw new ArgumentNullException(nameof(extractors)); - _options = options ?? throw new ArgumentNullException(nameof(options)); - _sizeSwitch = sizeSwitch ?? throw new ArgumentNullException(nameof(sizeSwitch)); + ArgumentNullException.ThrowIfNull(extractors); + Extractors = extractors; + ArgumentNullException.ThrowIfNull(options); + _options = options; + ArgumentNullException.ThrowIfNull(sizeSwitch); + _sizeSwitch = sizeSwitch; } /// diff --git a/src/Sentry.AspNetCore.Grpc/SentryGrpcInterceptor.cs b/src/Sentry.AspNetCore.Grpc/SentryGrpcInterceptor.cs index dd26151d99..52c7917bc1 100644 --- a/src/Sentry.AspNetCore.Grpc/SentryGrpcInterceptor.cs +++ b/src/Sentry.AspNetCore.Grpc/SentryGrpcInterceptor.cs @@ -27,7 +27,8 @@ public SentryGrpcInterceptor( Func hubAccessor, IOptions options) { - _hubAccessor = hubAccessor ?? throw new ArgumentNullException(nameof(hubAccessor)); + ArgumentNullException.ThrowIfNull(hubAccessor); + _hubAccessor = hubAccessor; _options = options.Value; var hub = _hubAccessor(); foreach (var callback in _options.ConfigureScopeCallbacks) diff --git a/src/Sentry.AspNetCore/SentryAspNetCoreBuilder.cs b/src/Sentry.AspNetCore/SentryAspNetCoreBuilder.cs index 00ff5ef3f4..f65cb04e5f 100644 --- a/src/Sentry.AspNetCore/SentryAspNetCoreBuilder.cs +++ b/src/Sentry.AspNetCore/SentryAspNetCoreBuilder.cs @@ -11,6 +11,7 @@ internal class SentryAspNetCoreBuilder : ISentryBuilder public SentryAspNetCoreBuilder(IServiceCollection services) { - Services = services ?? throw new ArgumentNullException(nameof(services)); + ArgumentNullException.ThrowIfNull(services); + Services = services; } } diff --git a/src/Sentry.AspNetCore/SentryMiddleware.cs b/src/Sentry.AspNetCore/SentryMiddleware.cs index 0b710a99b3..0fe959026f 100644 --- a/src/Sentry.AspNetCore/SentryMiddleware.cs +++ b/src/Sentry.AspNetCore/SentryMiddleware.cs @@ -62,7 +62,8 @@ public SentryMiddleware( IEnumerable eventProcessors, IEnumerable transactionProcessors) { - _getHub = getHub ?? throw new ArgumentNullException(nameof(getHub)); + ArgumentNullException.ThrowIfNull(getHub); + _getHub = getHub; _options = options.Value; _hostingEnvironment = hostingEnvironment; _logger = logger; diff --git a/src/Sentry.Extensions.Logging/DelegateLogEntryFilter.cs b/src/Sentry.Extensions.Logging/DelegateLogEntryFilter.cs index ef05e073dc..b29c3f7ca7 100644 --- a/src/Sentry.Extensions.Logging/DelegateLogEntryFilter.cs +++ b/src/Sentry.Extensions.Logging/DelegateLogEntryFilter.cs @@ -15,7 +15,10 @@ public class DelegateLogEntryFilter : ILogEntryFilter /// /// public DelegateLogEntryFilter(Func filter) - => _filter = filter ?? throw new ArgumentNullException(nameof(filter)); + { + ArgumentNullException.ThrowIfNull(filter); + _filter = filter; + } /// public bool Filter( diff --git a/src/Sentry/Extensibility/RequestBodyExtractionDispatcher.cs b/src/Sentry/Extensibility/RequestBodyExtractionDispatcher.cs index be8d0ad014..2cd231efa8 100644 --- a/src/Sentry/Extensibility/RequestBodyExtractionDispatcher.cs +++ b/src/Sentry/Extensibility/RequestBodyExtractionDispatcher.cs @@ -20,9 +20,12 @@ public class RequestBodyExtractionDispatcher : IRequestPayloadExtractor /// The max request size to capture. public RequestBodyExtractionDispatcher(IEnumerable extractors, SentryOptions options, Func sizeSwitch) { - Extractors = extractors ?? throw new ArgumentNullException(nameof(extractors)); - _options = options ?? throw new ArgumentNullException(nameof(options)); - _sizeSwitch = sizeSwitch ?? throw new ArgumentNullException(nameof(sizeSwitch)); + ArgumentNullException.ThrowIfNull(extractors); + Extractors = extractors; + ArgumentNullException.ThrowIfNull(options); + _options = options; + ArgumentNullException.ThrowIfNull(sizeSwitch); + _sizeSwitch = sizeSwitch; } /// diff --git a/src/Sentry/Internal/Extensions/CollectionsExtensions.cs b/src/Sentry/Internal/Extensions/CollectionsExtensions.cs index 8d7b6f7bdf..4184d5183c 100644 --- a/src/Sentry/Internal/Extensions/CollectionsExtensions.cs +++ b/src/Sentry/Internal/Extensions/CollectionsExtensions.cs @@ -75,12 +75,6 @@ public static IEnumerable> Append( public static IReadOnlyList AsReadOnly(this IList list) => list as IReadOnlyList ?? new ReadOnlyCollection(list); -#if !NET7_0_OR_GREATER - public static IReadOnlyDictionary AsReadOnly(this IDictionary dictionary) - where TKey : notnull => - new ReadOnlyDictionary(dictionary); -#endif - public static IEnumerable ExceptNulls(this IEnumerable source) => source.Where(x => x != null).Select(x => x!); diff --git a/src/Sentry/Internal/Http/DefaultSentryHttpClientFactory.cs b/src/Sentry/Internal/Http/DefaultSentryHttpClientFactory.cs index e6746283a6..98bcc91d8c 100644 --- a/src/Sentry/Internal/Http/DefaultSentryHttpClientFactory.cs +++ b/src/Sentry/Internal/Http/DefaultSentryHttpClientFactory.cs @@ -15,10 +15,7 @@ internal class DefaultSentryHttpClientFactory : ISentryHttpClientFactory /// The HTTP options. public HttpClient Create(SentryOptions options) { - if (options == null) - { - throw new ArgumentNullException(nameof(options)); - } + ArgumentNullException.ThrowIfNull(options); var handler = options.CreateHttpMessageHandler?.Invoke() ?? new HttpClientHandler(); if (handler is HttpClientHandler httpClientHandler) diff --git a/src/Sentry/Internal/Http/RetryAfterHandler.cs b/src/Sentry/Internal/Http/RetryAfterHandler.cs index 8478011d4d..de121037f9 100644 --- a/src/Sentry/Internal/Http/RetryAfterHandler.cs +++ b/src/Sentry/Internal/Http/RetryAfterHandler.cs @@ -28,7 +28,10 @@ public RetryAfterHandler(HttpMessageHandler innerHandler) internal RetryAfterHandler(HttpMessageHandler innerHandler, ISystemClock clock) : base(innerHandler) - => _clock = clock ?? throw new ArgumentNullException(nameof(clock)); + { + ArgumentNullException.ThrowIfNull(clock); + _clock = clock; + } /// /// Sends an HTTP request to the inner handler while verifying the Response status code for HTTP 429. diff --git a/src/Sentry/Internal/Polyfills.cs b/src/Sentry/Internal/Polyfills.cs index f5ce518ec3..375f577e73 100644 --- a/src/Sentry/Internal/Polyfills.cs +++ b/src/Sentry/Internal/Polyfills.cs @@ -63,31 +63,3 @@ public static void WriteRawValue(this Utf8JsonWriter writer, byte[] utf8Json) } #endif -// TODO: remove when updating Polyfill: https://github.com/getsentry/sentry-dotnet/pull/4879 -#if !NET6_0_OR_GREATER -internal static class EnumerableExtensions -{ - internal static bool TryGetNonEnumeratedCount(this IEnumerable source, out int count) - { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (source is ICollection genericCollection) - { - count = genericCollection.Count; - return true; - } - - if (source is ICollection collection) - { - count = collection.Count; - return true; - } - - count = 0; - return false; - } -} -#endif diff --git a/src/Sentry/Internal/SdkComposer.cs b/src/Sentry/Internal/SdkComposer.cs index d7263f8765..64eb86079e 100644 --- a/src/Sentry/Internal/SdkComposer.cs +++ b/src/Sentry/Internal/SdkComposer.cs @@ -12,7 +12,8 @@ internal class SdkComposer public SdkComposer(SentryOptions options, BackpressureMonitor? backpressureMonitor) { - _options = options ?? throw new ArgumentNullException(nameof(options)); + ArgumentNullException.ThrowIfNull(options); + _options = options; if (options.Dsn is null) { throw new ArgumentException("No DSN defined in the SentryOptions"); diff --git a/src/Sentry/Sentry.csproj b/src/Sentry/Sentry.csproj index db4cc45cd8..db018fb199 100644 --- a/src/Sentry/Sentry.csproj +++ b/src/Sentry/Sentry.csproj @@ -65,8 +65,13 @@ https://github.com/SimonCropp/Polyfill --> - + + + true + $(DefineConstants);FeatureHttp + $(DefineConstants);FeatureHttp + + + + + + From 6790c0fd059048aebb5b545485dc401ae667028a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Mar 2026 03:55:01 +0000 Subject: [PATCH 03/11] fix: correct spelling in comments Co-authored-by: jamescrosswell <728212+jamescrosswell@users.noreply.github.com> --- src/Directory.Build.props | 2 +- test/Directory.Build.props | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 2bf3cc7ef0..bc64593078 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -60,7 +60,7 @@ - + diff --git a/test/Directory.Build.props b/test/Directory.Build.props index 43c5f797ab..60116db326 100644 --- a/test/Directory.Build.props +++ b/test/Directory.Build.props @@ -79,7 +79,7 @@ - + From fdf2d466783d5c23158d991d28de5f8d8842ef67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20P=C3=B6lz?= <38893694+Flash0ver@users.noreply.github.com> Date: Wed, 11 Mar 2026 14:51:19 +0100 Subject: [PATCH 04/11] revert: Polyfill bump --- src/Directory.Build.props | 6 ---- src/Sentry.Analyzers/Sentry.Analyzers.csproj | 25 +++++------------ .../Extensions/CollectionsExtensions.cs | 6 ++++ src/Sentry/Internal/Polyfills.cs | 28 +++++++++++++++++++ src/Sentry/Sentry.csproj | 7 +---- test/Directory.Build.props | 6 ---- 6 files changed, 42 insertions(+), 36 deletions(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index bc64593078..e3e1feb526 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -60,10 +60,4 @@ - - - - - - diff --git a/src/Sentry.Analyzers/Sentry.Analyzers.csproj b/src/Sentry.Analyzers/Sentry.Analyzers.csproj index 2f6d4193fd..e3a9096869 100644 --- a/src/Sentry.Analyzers/Sentry.Analyzers.csproj +++ b/src/Sentry.Analyzers/Sentry.Analyzers.csproj @@ -19,24 +19,13 @@ - - - - - - - - true - - - - - $([System.String]::Copy('$(DefineConstants)').Replace('FeatureMemory','').Replace(';;',';')) - - + + + + diff --git a/src/Sentry/Internal/Extensions/CollectionsExtensions.cs b/src/Sentry/Internal/Extensions/CollectionsExtensions.cs index 4184d5183c..8d7b6f7bdf 100644 --- a/src/Sentry/Internal/Extensions/CollectionsExtensions.cs +++ b/src/Sentry/Internal/Extensions/CollectionsExtensions.cs @@ -75,6 +75,12 @@ public static IEnumerable> Append( public static IReadOnlyList AsReadOnly(this IList list) => list as IReadOnlyList ?? new ReadOnlyCollection(list); +#if !NET7_0_OR_GREATER + public static IReadOnlyDictionary AsReadOnly(this IDictionary dictionary) + where TKey : notnull => + new ReadOnlyDictionary(dictionary); +#endif + public static IEnumerable ExceptNulls(this IEnumerable source) => source.Where(x => x != null).Select(x => x!); diff --git a/src/Sentry/Internal/Polyfills.cs b/src/Sentry/Internal/Polyfills.cs index 375f577e73..f5ce518ec3 100644 --- a/src/Sentry/Internal/Polyfills.cs +++ b/src/Sentry/Internal/Polyfills.cs @@ -63,3 +63,31 @@ public static void WriteRawValue(this Utf8JsonWriter writer, byte[] utf8Json) } #endif +// TODO: remove when updating Polyfill: https://github.com/getsentry/sentry-dotnet/pull/4879 +#if !NET6_0_OR_GREATER +internal static class EnumerableExtensions +{ + internal static bool TryGetNonEnumeratedCount(this IEnumerable source, out int count) + { + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } + + if (source is ICollection genericCollection) + { + count = genericCollection.Count; + return true; + } + + if (source is ICollection collection) + { + count = collection.Count; + return true; + } + + count = 0; + return false; + } +} +#endif diff --git a/src/Sentry/Sentry.csproj b/src/Sentry/Sentry.csproj index 7a26404b02..7d70eff43d 100644 --- a/src/Sentry/Sentry.csproj +++ b/src/Sentry/Sentry.csproj @@ -65,13 +65,8 @@ https://github.com/SimonCropp/Polyfill --> - + - - true - $(DefineConstants);FeatureHttp - $(DefineConstants);FeatureHttp - - - - - - From 5553ee046ec48eccf7f141cb20fa34481ab8218f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20P=C3=B6lz?= <38893694+Flash0ver@users.noreply.github.com> Date: Wed, 11 Mar 2026 15:05:46 +0100 Subject: [PATCH 05/11] ref: Add internal Polyfill for ThrowIfNull --- src/Sentry/Internal/Polyfills.cs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/Sentry/Internal/Polyfills.cs b/src/Sentry/Internal/Polyfills.cs index f5ce518ec3..772b7b7506 100644 --- a/src/Sentry/Internal/Polyfills.cs +++ b/src/Sentry/Internal/Polyfills.cs @@ -91,3 +91,26 @@ internal static bool TryGetNonEnumeratedCount(this IEnumerable } } #endif + +// TODO: remove when updating Polyfill: https://github.com/getsentry/sentry-dotnet/pull/4879 +#if !NET6_0_OR_GREATER +internal static class ArgumentNullExceptionExtensions +{ + extension(ArgumentNullException) + { + internal static void ThrowIfNull([NotNull] object? argument, [CallerArgumentExpression(nameof(argument))] string? paramName = null) + { + if (argument is null) + { + Throw(paramName); + } + } + } + + [DoesNotReturn] + private static void Throw(string? paramName) + { + throw new ArgumentNullException(paramName); + } +} +#endif From 9901bc65277cd409a2fb0af3bdca1211522580cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20P=C3=B6lz?= <38893694+Flash0ver@users.noreply.github.com> Date: Wed, 11 Mar 2026 15:10:42 +0100 Subject: [PATCH 06/11] style: consistent new-line after argument-null-validation --- src/Sentry.AspNet/Internal/SystemWebRequestEventProcessor.cs | 3 ++- .../ProtobufRequestExtractionDispatcher.cs | 5 +++-- src/Sentry.AspNetCore.Grpc/SentryGrpcInterceptor.cs | 1 + src/Sentry.AspNetCore/SentryAspNetCoreBuilder.cs | 1 + src/Sentry.AspNetCore/SentryMiddleware.cs | 1 + src/Sentry.Extensions.Logging/DelegateLogEntryFilter.cs | 1 + src/Sentry/Extensibility/RequestBodyExtractionDispatcher.cs | 5 +++-- src/Sentry/Internal/Http/RetryAfterHandler.cs | 1 + src/Sentry/Internal/SdkComposer.cs | 1 + src/Sentry/SentryClient.cs | 1 + src/Sentry/SentryOptions.cs | 1 + 11 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/Sentry.AspNet/Internal/SystemWebRequestEventProcessor.cs b/src/Sentry.AspNet/Internal/SystemWebRequestEventProcessor.cs index 0c00a93e86..ba4cfbd735 100644 --- a/src/Sentry.AspNet/Internal/SystemWebRequestEventProcessor.cs +++ b/src/Sentry.AspNet/Internal/SystemWebRequestEventProcessor.cs @@ -14,9 +14,10 @@ internal class SystemWebRequestEventProcessor : ISentryEventProcessor public SystemWebRequestEventProcessor(IRequestPayloadExtractor payloadExtractor, SentryOptions options) { + ArgumentNullException.ThrowIfNull(payloadExtractor); ArgumentNullException.ThrowIfNull(options); + _options = options; - ArgumentNullException.ThrowIfNull(payloadExtractor); PayloadExtractor = payloadExtractor; } diff --git a/src/Sentry.AspNetCore.Grpc/ProtobufRequestExtractionDispatcher.cs b/src/Sentry.AspNetCore.Grpc/ProtobufRequestExtractionDispatcher.cs index 10f7d713f0..0749877ba0 100644 --- a/src/Sentry.AspNetCore.Grpc/ProtobufRequestExtractionDispatcher.cs +++ b/src/Sentry.AspNetCore.Grpc/ProtobufRequestExtractionDispatcher.cs @@ -24,10 +24,11 @@ public ProtobufRequestExtractionDispatcher(IEnumerable sizeSwitch) { ArgumentNullException.ThrowIfNull(extractors); - Extractors = extractors; ArgumentNullException.ThrowIfNull(options); - _options = options; ArgumentNullException.ThrowIfNull(sizeSwitch); + + Extractors = extractors; + _options = options; _sizeSwitch = sizeSwitch; } diff --git a/src/Sentry.AspNetCore.Grpc/SentryGrpcInterceptor.cs b/src/Sentry.AspNetCore.Grpc/SentryGrpcInterceptor.cs index 52c7917bc1..c08fd6ccfc 100644 --- a/src/Sentry.AspNetCore.Grpc/SentryGrpcInterceptor.cs +++ b/src/Sentry.AspNetCore.Grpc/SentryGrpcInterceptor.cs @@ -28,6 +28,7 @@ public SentryGrpcInterceptor( IOptions options) { ArgumentNullException.ThrowIfNull(hubAccessor); + _hubAccessor = hubAccessor; _options = options.Value; var hub = _hubAccessor(); diff --git a/src/Sentry.AspNetCore/SentryAspNetCoreBuilder.cs b/src/Sentry.AspNetCore/SentryAspNetCoreBuilder.cs index f65cb04e5f..180ce95779 100644 --- a/src/Sentry.AspNetCore/SentryAspNetCoreBuilder.cs +++ b/src/Sentry.AspNetCore/SentryAspNetCoreBuilder.cs @@ -12,6 +12,7 @@ internal class SentryAspNetCoreBuilder : ISentryBuilder public SentryAspNetCoreBuilder(IServiceCollection services) { ArgumentNullException.ThrowIfNull(services); + Services = services; } } diff --git a/src/Sentry.AspNetCore/SentryMiddleware.cs b/src/Sentry.AspNetCore/SentryMiddleware.cs index 0fe959026f..3f7b9f54f6 100644 --- a/src/Sentry.AspNetCore/SentryMiddleware.cs +++ b/src/Sentry.AspNetCore/SentryMiddleware.cs @@ -63,6 +63,7 @@ public SentryMiddleware( IEnumerable transactionProcessors) { ArgumentNullException.ThrowIfNull(getHub); + _getHub = getHub; _options = options.Value; _hostingEnvironment = hostingEnvironment; diff --git a/src/Sentry.Extensions.Logging/DelegateLogEntryFilter.cs b/src/Sentry.Extensions.Logging/DelegateLogEntryFilter.cs index b29c3f7ca7..f8ead34ab8 100644 --- a/src/Sentry.Extensions.Logging/DelegateLogEntryFilter.cs +++ b/src/Sentry.Extensions.Logging/DelegateLogEntryFilter.cs @@ -17,6 +17,7 @@ public class DelegateLogEntryFilter : ILogEntryFilter public DelegateLogEntryFilter(Func filter) { ArgumentNullException.ThrowIfNull(filter); + _filter = filter; } diff --git a/src/Sentry/Extensibility/RequestBodyExtractionDispatcher.cs b/src/Sentry/Extensibility/RequestBodyExtractionDispatcher.cs index 2cd231efa8..09d03ca6db 100644 --- a/src/Sentry/Extensibility/RequestBodyExtractionDispatcher.cs +++ b/src/Sentry/Extensibility/RequestBodyExtractionDispatcher.cs @@ -21,10 +21,11 @@ public class RequestBodyExtractionDispatcher : IRequestPayloadExtractor public RequestBodyExtractionDispatcher(IEnumerable extractors, SentryOptions options, Func sizeSwitch) { ArgumentNullException.ThrowIfNull(extractors); - Extractors = extractors; ArgumentNullException.ThrowIfNull(options); - _options = options; ArgumentNullException.ThrowIfNull(sizeSwitch); + + Extractors = extractors; + _options = options; _sizeSwitch = sizeSwitch; } diff --git a/src/Sentry/Internal/Http/RetryAfterHandler.cs b/src/Sentry/Internal/Http/RetryAfterHandler.cs index de121037f9..a752a7c439 100644 --- a/src/Sentry/Internal/Http/RetryAfterHandler.cs +++ b/src/Sentry/Internal/Http/RetryAfterHandler.cs @@ -30,6 +30,7 @@ internal RetryAfterHandler(HttpMessageHandler innerHandler, ISystemClock clock) : base(innerHandler) { ArgumentNullException.ThrowIfNull(clock); + _clock = clock; } diff --git a/src/Sentry/Internal/SdkComposer.cs b/src/Sentry/Internal/SdkComposer.cs index 64eb86079e..96a9e2015d 100644 --- a/src/Sentry/Internal/SdkComposer.cs +++ b/src/Sentry/Internal/SdkComposer.cs @@ -13,6 +13,7 @@ internal class SdkComposer public SdkComposer(SentryOptions options, BackpressureMonitor? backpressureMonitor) { ArgumentNullException.ThrowIfNull(options); + _options = options; if (options.Dsn is null) { diff --git a/src/Sentry/SentryClient.cs b/src/Sentry/SentryClient.cs index 57940d2b4f..d1b6ca3880 100644 --- a/src/Sentry/SentryClient.cs +++ b/src/Sentry/SentryClient.cs @@ -46,6 +46,7 @@ internal SentryClient( BackpressureMonitor? backpressureMonitor = null) { ArgumentNullException.ThrowIfNull(options); + _options = options; _backpressureMonitor = backpressureMonitor; _randomValuesFactory = randomValuesFactory ?? new SynchronizedRandomValuesFactory(); diff --git a/src/Sentry/SentryOptions.cs b/src/Sentry/SentryOptions.cs index 85a9ac2e55..6980c8960a 100644 --- a/src/Sentry/SentryOptions.cs +++ b/src/Sentry/SentryOptions.cs @@ -1686,6 +1686,7 @@ public IEnumerable GetAllExceptionProcessors() public SentryOptions UseStackTraceFactory(ISentryStackTraceFactory sentryStackTraceFactory) { ArgumentNullException.ThrowIfNull(sentryStackTraceFactory); + SentryStackTraceFactory = sentryStackTraceFactory; return this; } From 43b3e90f914bee887cf25b1bce74eb43bddf857d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20P=C3=B6lz?= <38893694+Flash0ver@users.noreply.github.com> Date: Wed, 11 Mar 2026 15:19:37 +0100 Subject: [PATCH 07/11] ref: more usage of polyfill --- src/Sentry/Internal/Polyfills.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Sentry/Internal/Polyfills.cs b/src/Sentry/Internal/Polyfills.cs index 772b7b7506..15f47278cc 100644 --- a/src/Sentry/Internal/Polyfills.cs +++ b/src/Sentry/Internal/Polyfills.cs @@ -69,10 +69,7 @@ internal static class EnumerableExtensions { internal static bool TryGetNonEnumeratedCount(this IEnumerable source, out int count) { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + ArgumentNullException.ThrowIfNull(source); if (source is ICollection genericCollection) { From bb3f740da48ac440cd2461caa0f7bbe0c6dc2fdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20P=C3=B6lz?= <38893694+Flash0ver@users.noreply.github.com> Date: Wed, 11 Mar 2026 15:19:59 +0100 Subject: [PATCH 08/11] test: avoid unnecessary ArgumentNullException --- test/Sentry.Tests/Protocol/DsnTests.cs | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/test/Sentry.Tests/Protocol/DsnTests.cs b/test/Sentry.Tests/Protocol/DsnTests.cs index 41e91b702e..d9eb15349c 100644 --- a/test/Sentry.Tests/Protocol/DsnTests.cs +++ b/test/Sentry.Tests/Protocol/DsnTests.cs @@ -279,15 +279,8 @@ public override string ToString() private static void AssertEqual(DsnTestCase @case, Dsn dsn) { - if (@case == null) - { - throw new ArgumentNullException(nameof(@case)); - } - - if (dsn == null) - { - throw new ArgumentNullException(nameof(dsn)); - } + Assert.NotNull(@case); + Assert.NotNull(dsn); var uri = dsn.GetStoreEndpointUri(); From 4327884482430b17d234464e4c32b83de5e3e479 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20P=C3=B6lz?= <38893694+Flash0ver@users.noreply.github.com> Date: Tue, 17 Mar 2026 13:54:44 +0100 Subject: [PATCH 09/11] chore: Add ExtensionMarkerAttribute for .NET 9.0 and lower --- src/Sentry/Polyfilling/ExtensionMarkerAttribute.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/Sentry/Polyfilling/ExtensionMarkerAttribute.cs diff --git a/src/Sentry/Polyfilling/ExtensionMarkerAttribute.cs b/src/Sentry/Polyfilling/ExtensionMarkerAttribute.cs new file mode 100644 index 0000000000..ee982ce8e9 --- /dev/null +++ b/src/Sentry/Polyfilling/ExtensionMarkerAttribute.cs @@ -0,0 +1,14 @@ +// ReSharper disable CheckNamespace +namespace System.Runtime.CompilerServices; + +#if !NET10_0_OR_GREATER +[EditorBrowsable(EditorBrowsableState.Never)] +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)] +internal sealed class ExtensionMarkerAttribute : Attribute +{ + public ExtensionMarkerAttribute(string name) + => Name = name; + + public string Name { get; } +} +#endif From 7dccdbb3a21c5d3acd5f8de23303aa26d0451dce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20P=C3=B6lz?= <38893694+Flash0ver@users.noreply.github.com> Date: Tue, 17 Mar 2026 14:30:58 +0100 Subject: [PATCH 10/11] chore: Remove ExtensionMarkerAttribute for .NET 9.0 and lower --- src/Sentry/Polyfilling/ExtensionMarkerAttribute.cs | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 src/Sentry/Polyfilling/ExtensionMarkerAttribute.cs diff --git a/src/Sentry/Polyfilling/ExtensionMarkerAttribute.cs b/src/Sentry/Polyfilling/ExtensionMarkerAttribute.cs deleted file mode 100644 index ee982ce8e9..0000000000 --- a/src/Sentry/Polyfilling/ExtensionMarkerAttribute.cs +++ /dev/null @@ -1,14 +0,0 @@ -// ReSharper disable CheckNamespace -namespace System.Runtime.CompilerServices; - -#if !NET10_0_OR_GREATER -[EditorBrowsable(EditorBrowsableState.Never)] -[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)] -internal sealed class ExtensionMarkerAttribute : Attribute -{ - public ExtensionMarkerAttribute(string name) - => Name = name; - - public string Name { get; } -} -#endif From 4c80e697f78069eb32e1529f4abc88dd0e364ba3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20P=C3=B6lz?= <38893694+Flash0ver@users.noreply.github.com> Date: Tue, 17 Mar 2026 14:31:32 +0100 Subject: [PATCH 11/11] fix: make ThrowIfNull static-extension-method public but keep the Extension container class ArgumentNullExceptionExtensions internal --- src/Sentry/Internal/Polyfills.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Sentry/Internal/Polyfills.cs b/src/Sentry/Internal/Polyfills.cs index 15f47278cc..e525de2b5e 100644 --- a/src/Sentry/Internal/Polyfills.cs +++ b/src/Sentry/Internal/Polyfills.cs @@ -95,7 +95,7 @@ internal static class ArgumentNullExceptionExtensions { extension(ArgumentNullException) { - internal static void ThrowIfNull([NotNull] object? argument, [CallerArgumentExpression(nameof(argument))] string? paramName = null) + public static void ThrowIfNull([NotNull] object? argument, [CallerArgumentExpression(nameof(argument))] string? paramName = null) { if (argument is null) {