Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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 CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## Unreleased

### Fixes

- Sentry Tracing middleware crashed ASP.NET Core in .NET 10 in 6.0.0-rc.1 and earlier ([#4747](https://github.com/getsentry/sentry-dotnet/pull/4747))

## 6.0.0-rc.1

### BREAKING CHANGES
Expand Down
8 changes: 3 additions & 5 deletions src/Sentry.AspNetCore/SentryTracingMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ public async Task InvokeAsync(HttpContext context)
catch (Exception e)
{
exception = e;
// Rethrow immediately so as not to disrupt the .net 10 pipeline behaviour
// See: https://github.com/getsentry/sentry-dotnet/issues/4735
ExceptionDispatchInfo.Capture(e).Throw();
}
finally
{
Expand Down Expand Up @@ -212,11 +215,6 @@ public async Task InvokeAsync(HttpContext context)
transaction.Finish(exception, status);
}
}

if (exception is not null)
{
ExceptionDispatchInfo.Capture(exception).Throw();
}
}
}
}
54 changes: 54 additions & 0 deletions test/Sentry.AspNetCore.Tests/SentryTracingMiddlewareTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,60 @@ public async Task Transaction_binds_exception_thrown()
Assert.Equal(SpanStatus.InternalError, span?.Status);
}

[Fact]
public async Task ExceptionThrownAsync_DoesNotCrashKestrel()
{
var sentryClient = Substitute.For<ISentryClient>();
var options = new SentryAspNetCoreOptions
{
Dsn = ValidDsn,
TracesSampleRate = 1,
AutoRegisterTracing = false
};

var hub = new Hub(options, sentryClient);

var server = new TestServer(new WebHostBuilder()
.UseSentry()
.ConfigureServices(services =>
{
services.RemoveAll(typeof(Func<IHub>));
services.AddSingleton<Func<IHub>>(() => hub);
services.AddRouting();
}).Configure(app =>
{
app.UseRouting();
app.UseSentryTracing();
app.UseEndpoints(routes =>
{
routes.Map("/", _ => Task.CompletedTask);
routes.Map("/crash", async _ =>
{
await Task.Yield();
throw new Exception();
});
});
}));

var client = server.CreateClient();

// Act
try
{
await client.GetStringAsync("/crash");
}
// Expected error.
catch
{
// ignored
}

// Assert
// Make sure Kestrel is still alive by making another request
var response = await client.GetAsync("/");
response.StatusCode.Should().Be(System.Net.HttpStatusCode.OK);
}
Comment on lines 619 to 668
Copy link

Choose a reason for hiding this comment

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

This test validates that the server remains responsive after an exception, which is good. However, it lacks assertions to verify that the exception was properly recorded in Sentry and bound to the transaction. Consider adding assertions similar to the existing Transaction_binds_exception_thrown test to ensure that hub.ExceptionToSpanMap contains the exception and that the transaction was finished with an error status. This would provide more comprehensive validation of the exception handling flow.
Severity: MEDIUM

🤖 Prompt for AI Agent

Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: test/Sentry.AspNetCore.Tests/SentryTracingMiddlewareTests.cs#L619-L669

Potential issue: This test validates that the server remains responsive after an
exception, which is good. However, it lacks assertions to verify that the exception was
properly recorded in Sentry and bound to the transaction. Consider adding assertions
similar to the existing `Transaction_binds_exception_thrown` test to ensure that
`hub.ExceptionToSpanMap` contains the exception and that the transaction was finished
with an error status. This would provide more comprehensive validation of the exception
handling flow.

Did we get this right? 👍 / 👎 to inform future reviews.

Reference_id: 2766746

Copy link
Member

@Flash0ver Flash0ver Nov 18, 2025

Choose a reason for hiding this comment

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

True.
When removing the re-throw entirely

// Rethrow immediately so as not to disrupt the .net 10 pipeline behaviour
// See: https://github.com/getsentry/sentry-dotnet/issues/4735
ExceptionDispatchInfo.Capture(e).Throw();

no test in SentryTracingMiddlewareTests fails.

However, other tests are failing

  • Sentry.AspNetCore.Tests.IntegrationsTests.CaptureException_UseExceptionHandler_SetRouteDataFromInitialRequest
  • Sentry.Google.Cloud.Functions.Tests.IntegrationTests.SentryIntegrationTest_CaptureUnhandledException

Is it worth adding an assertion to SentryTracingMiddlewareTests, too?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It's not really the point of this fix. We could address it separately if we think we're lacking test coverage.


[Fact]
public async Task Transaction_TransactionNameProviderSetSet_TransactionNameSet()
{
Expand Down