diff --git a/CHANGELOG.md b/CHANGELOG.md index ed49e27fee..8e1d5959e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ - Add additional primitive values as tags on SentryLogger ([#1246](https://github.com/getsentry/sentry-dotnet/pull/1246)) +### Fixes + +- Events are now sent on Google Gloud Functions Integration ([#1249](https://github.com/getsentry/sentry-dotnet/pull/1249)) + ## 3.9.4 ### Fixes diff --git a/src/Sentry.AspNetCore/Properties/AssemblyInfo.cs b/src/Sentry.AspNetCore/Properties/AssemblyInfo.cs index 9d6c85d316..0482d85ac7 100644 --- a/src/Sentry.AspNetCore/Properties/AssemblyInfo.cs +++ b/src/Sentry.AspNetCore/Properties/AssemblyInfo.cs @@ -2,5 +2,6 @@ [assembly: InternalsVisibleTo("Sentry.AspNetCore.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010059964a931488bcdbd14657f1ee0df32df61b57b3d14d7290c262c2cc9ddaad6ec984044f761f778e1823049d2cb996a4f58c8ea5b46c37891414cb34b4036b1c178d7b582289d2eef3c0f1e9b692c229a306831ee3d371d9e883f0eb0f74aeac6c6ab8c85fd1ec04b267e15a31532c4b4e2191f5980459db4dce0081f1050fb8")] [assembly: InternalsVisibleTo("Sentry.AspNetCore.Grpc, PublicKey=002400000480000094000000060200000024000052534131000400000100010059964a931488bcdbd14657f1ee0df32df61b57b3d14d7290c262c2cc9ddaad6ec984044f761f778e1823049d2cb996a4f58c8ea5b46c37891414cb34b4036b1c178d7b582289d2eef3c0f1e9b692c229a306831ee3d371d9e883f0eb0f74aeac6c6ab8c85fd1ec04b267e15a31532c4b4e2191f5980459db4dce0081f1050fb8")] +[assembly: InternalsVisibleTo("Sentry.Google.Cloud.Functions, PublicKey=002400000480000094000000060200000024000052534131000400000100010059964a931488bcdbd14657f1ee0df32df61b57b3d14d7290c262c2cc9ddaad6ec984044f761f778e1823049d2cb996a4f58c8ea5b46c37891414cb34b4036b1c178d7b582289d2eef3c0f1e9b692c229a306831ee3d371d9e883f0eb0f74aeac6c6ab8c85fd1ec04b267e15a31532c4b4e2191f5980459db4dce0081f1050fb8")] [assembly: InternalsVisibleTo("Sentry.Google.Cloud.Functions.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010059964a931488bcdbd14657f1ee0df32df61b57b3d14d7290c262c2cc9ddaad6ec984044f761f778e1823049d2cb996a4f58c8ea5b46c37891414cb34b4036b1c178d7b582289d2eef3c0f1e9b692c229a306831ee3d371d9e883f0eb0f74aeac6c6ab8c85fd1ec04b267e15a31532c4b4e2191f5980459db4dce0081f1050fb8")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] diff --git a/src/Sentry.AspNetCore/SentryAspNetCoreOptions.cs b/src/Sentry.AspNetCore/SentryAspNetCoreOptions.cs index 677f44b7f6..6bad0a2d8e 100644 --- a/src/Sentry.AspNetCore/SentryAspNetCoreOptions.cs +++ b/src/Sentry.AspNetCore/SentryAspNetCoreOptions.cs @@ -34,6 +34,11 @@ public class SentryAspNetCoreOptions : SentryLoggingOptions /// public bool FlushOnCompletedRequest { get; set; } + /// + /// Flush before the request gets completed. + /// + internal bool FlushBeforeRequestCompleted { get; set; } + /// /// How long to wait for the flush to finish. Defaults to 2 seconds. /// diff --git a/src/Sentry.AspNetCore/SentryMiddleware.cs b/src/Sentry.AspNetCore/SentryMiddleware.cs index c2fd8aad87..723af08be2 100644 --- a/src/Sentry.AspNetCore/SentryMiddleware.cs +++ b/src/Sentry.AspNetCore/SentryMiddleware.cs @@ -117,14 +117,29 @@ public async Task InvokeAsync(HttpContext context) { CaptureException(exceptionFeature.Error, "IExceptionHandlerFeature"); } + if (_options.FlushBeforeRequestCompleted) + { + await FlushBeforeCompleted().ConfigureAwait(false); + } } catch (Exception e) { CaptureException(e, "SentryMiddleware.UnhandledException"); + if (_options.FlushBeforeRequestCompleted) + { + await FlushBeforeCompleted().ConfigureAwait(false); + } ExceptionDispatchInfo.Capture(e).Throw(); } + async Task FlushBeforeCompleted() + { + // Some environments disables the application after sending a request, + // making the OnCompleted flush to not work. + await hub.FlushAsync(timeout: _options.FlushTimeout).ConfigureAwait(false); + } + void CaptureException(Exception e, string mechanism) { e.Data[Mechanism.HandledKey] = false; diff --git a/src/Sentry.Google.Cloud.Functions/SentryStartup.cs b/src/Sentry.Google.Cloud.Functions/SentryStartup.cs index 4bbfc485ac..e5bf11d696 100644 --- a/src/Sentry.Google.Cloud.Functions/SentryStartup.cs +++ b/src/Sentry.Google.Cloud.Functions/SentryStartup.cs @@ -32,7 +32,7 @@ public override void ConfigureLogging(WebHostBuilderContext context, ILoggingBui logging.Services.Configure(options => { // Make sure all events are flushed out - options.FlushOnCompletedRequest = true; + options.FlushBeforeRequestCompleted = true; }); logging.Services.AddSingleton, SentryAspNetCoreOptionsSetup>(); diff --git a/test/Sentry.AspNetCore.Tests/SentryMiddlewareTests.cs b/test/Sentry.AspNetCore.Tests/SentryMiddlewareTests.cs index 621842a3e7..4e85044365 100644 --- a/test/Sentry.AspNetCore.Tests/SentryMiddlewareTests.cs +++ b/test/Sentry.AspNetCore.Tests/SentryMiddlewareTests.cs @@ -456,11 +456,27 @@ public async Task InvokeAsync_FlushOnCompletedRequestWhenFalse_DoesNotCallFlushA await _fixture.Hub.DidNotReceive().FlushAsync(Arg.Any()); } + [Fact] + public async Task InvokeAsync_FlushBeforeRequestCompletedWhenFalse_DoesNotCallFlushAsync() + { + var sut = _fixture.GetSut(); + _fixture.Options.FlushBeforeRequestCompleted = false; + var response = Substitute.For(); + _ = _fixture.HttpContext.Response.Returns(response); + _ = response.HttpContext.Returns(_fixture.HttpContext); + response.When(r => r.OnCompleted(Arg.Any>())).Do(info => info.Arg>()()); + + await sut.InvokeAsync(_fixture.HttpContext); + + await _fixture.Hub.DidNotReceive().FlushAsync(Arg.Any()); + } + [Fact] public async Task InvokeAsync_DisabledHub_DoesNotCallFlushAsync() { var sut = _fixture.GetSut(); _fixture.Options.FlushOnCompletedRequest = true; + _fixture.Options.FlushBeforeRequestCompleted = true; _ = _fixture.Hub.IsEnabled.Returns(false); var response = Substitute.For(); _ = _fixture.HttpContext.Response.Returns(response); @@ -488,5 +504,22 @@ public async Task InvokeAsync_FlushOnCompletedRequestTrue_RespectsTimeout() await _fixture.Hub.Received(1).FlushAsync(timeout); } + + [Fact] + public async Task InvokeAsync_FlushBeforeRequestCompletedTrue_RespectsTimeout() + { + var timeout = TimeSpan.FromSeconds(10); + var sut = _fixture.GetSut(); + _fixture.Options.FlushBeforeRequestCompleted = true; + _fixture.Options.FlushTimeout = timeout; + var response = Substitute.For(); + _ = _fixture.HttpContext.Response.Returns(response); + _ = response.HttpContext.Returns(_fixture.HttpContext); + response.When(r => r.OnCompleted(Arg.Any>())).Do(info => info.Arg>()()); + + await sut.InvokeAsync(_fixture.HttpContext); + + await _fixture.Hub.Received(1).FlushAsync(timeout); + } } } diff --git a/test/Sentry.Google.Cloud.Functions.Tests/SentryStartupTests.cs b/test/Sentry.Google.Cloud.Functions.Tests/SentryStartupTests.cs index b71e770e80..c281722446 100644 --- a/test/Sentry.Google.Cloud.Functions.Tests/SentryStartupTests.cs +++ b/test/Sentry.Google.Cloud.Functions.Tests/SentryStartupTests.cs @@ -44,7 +44,7 @@ public void ConfigureLogging_SentryAspNetCoreOptions_FlushOnCompletedRequestTrue var provider = LoggingBuilder.Services.BuildServiceProvider(); var option = provider.GetRequiredService>(); - Assert.True(option.Value.FlushOnCompletedRequest); + Assert.True(option.Value.FlushBeforeRequestCompleted); } [Theory, MemberData(nameof(ExpectedServices))]