Skip to content
Prev Previous commit
Next Next commit
Added device tests for the Android BeforeSendWrapper
  • Loading branch information
jamescrosswell committed Feb 4, 2025
commit 664b37f646d14128a3c8439441fe8b3fc2a92044
33 changes: 20 additions & 13 deletions src/Sentry/Platforms/Android/SentrySdk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,19 +100,7 @@ private static void InitSentryAndroidSdk(SentryOptions options)
}
}

SentryEvent? BeforeSendWrapper(SentryEvent evt, SentryHint hint)
{
if (evt.SentryExceptions?.SingleOrDefault() is { Type: "SIGSEGV", Value: "Segfault" } exception)
{
options.LogDebug("Suppressing SIGSEGV (this will be thrown as a managed exception instead)");
return null;
}
// Call the user defined BeforeSend callback, if it's defined - otherwise return the event as-is
return (options.Native.EnableBeforeSend && options.BeforeSendInternal is { } beforeSend)
? beforeSend(evt, hint)
: evt;
}
o.BeforeSend = new BeforeSendCallback(BeforeSendWrapper, options, o);
o.BeforeSend = new BeforeSendCallback(BeforeSendWrapper(options), options, o);

// These options are from SentryAndroidOptions
o.AttachScreenshot = options.Native.AttachScreenshot;
Expand Down Expand Up @@ -182,6 +170,25 @@ private static void InitSentryAndroidSdk(SentryOptions options)
// TODO: Pause/Resume
}

internal static Func<SentryEvent, SentryHint, SentryEvent?> BeforeSendWrapper(SentryOptions options)
{
return (evt, hint) =>
{
// Suppress SIGSEGV errors.
// See: https://github.com/getsentry/sentry-dotnet/pull/3903
if (evt.SentryExceptions?.SingleOrDefault() is { Type: "SIGSEGV", Value: "Segfault" } exception)
{
options.LogDebug("Suppressing SIGSEGV (this will be thrown as a managed exception instead)");
return null;
}

// Call the user defined BeforeSend callback, if it's defined - otherwise return the event as-is
return (options.Native.EnableBeforeSend && options.BeforeSendInternal is { } beforeSend)
? beforeSend(evt, hint)
: evt;
};
}

private static void AndroidEnvironment_UnhandledExceptionRaiser(object? _, RaiseThrowableEventArgs e)
{
var description = "This exception was caught by the Android global error handler.";
Expand Down
89 changes: 89 additions & 0 deletions test/Sentry.Tests/Platforms/Android/SentrySdkTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#if ANDROID
namespace Sentry.Tests.Platforms.Android;

public class SentrySdkTests
{
[Fact]
public void BeforeSendWrapper_SuppressSIGSEGV_ReturnsNull()
{
// Arrange
var options = new SentryOptions();
var evt = new SentryEvent
{
SentryExceptions = new[]
{
new SentryException
{
Type = "SIGSEGV",
Value = "Segfault"
}
}
};
var hint = new SentryHint();

// Act
var result = SentrySdk.BeforeSendWrapper(options).Invoke(evt, hint);

// Assert
result.Should().BeNull();
}

[Fact]
public void BeforeSendWrapper_BeforeSendCallbackDefined_CallsBeforeSend()
{
// Arrange
var beforeSend = Substitute.For<Func<SentryEvent, SentryHint, SentryEvent>>();
beforeSend.Invoke(Arg.Any<SentryEvent>(), Arg.Any<SentryHint>()).Returns(callInfo => callInfo.Arg<SentryEvent>());

var options = new SentryOptions();
options.Native.EnableBeforeSend = true;
options.SetBeforeSend(beforeSend);
var evt = new SentryEvent();
var hint = new SentryHint();

// Act
var result = SentrySdk.BeforeSendWrapper(options).Invoke(evt, hint);

// Assert
beforeSend.Received(1).Invoke(Arg.Any<SentryEvent>(), Arg.Any<SentryHint>());
result.Should().Be(evt);
}

[Fact]
public void BeforeSendWrapper_NoBeforeSendCallback_ReturnsEvent()
{
// Arrange
var options = new SentryOptions();
options.Native.EnableBeforeSend = true;
var evt = new SentryEvent();
var hint = new SentryHint();

// Act
var result = SentrySdk.BeforeSendWrapper(options).Invoke(evt, hint);

// Assert
result.Should().Be(evt);
}

[Fact]
public void BeforeSendWrapper_NativeBeforeSendDisabled_ReturnsEvent()
{
// Arrange
var beforeSend = Substitute.For<Func<SentryEvent, SentryHint, SentryEvent>>();
beforeSend.Invoke(Arg.Any<SentryEvent>(), Arg.Any<SentryHint>()).Returns(_ => null);

var options = new SentryOptions();
options.SetBeforeSend(beforeSend);
options.Native.EnableBeforeSend = false;
var evt = new SentryEvent();
var hint = new SentryHint();

// Act
var result = SentrySdk.BeforeSendWrapper(options).Invoke(evt, hint);

// Assert
beforeSend.DidNotReceive().Invoke(Arg.Any<SentryEvent>(), Arg.Any<SentryHint>());
result.Should().Be(evt);
}
}
#endif
Loading