Skip to content

fix: Moved late option mutation into Init #2239

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 61 commits into
base: main
Choose a base branch
from

Conversation

bitsandfoxes
Copy link
Contributor

@bitsandfoxes bitsandfoxes commented Jul 10, 2025

This is a follow-up on #2227 as this was getting already kinda big.

Goal

This PR moves adding integrations that depend on certain flags into the Init call to be added "late" to keep the SDKs behavious consistent between self and manual initialization.

Context

There are two ways SentryUnityOptions gets created:

  • Self-Initializing: The SDK reads the .asset and creates new options from the ScriptableObject
  • Manual-Initialization: User code initializes the SDK

In both cases, changes to the options need to be made at the same time. This leaves either the constructor or right before initialization.

This means that handling those "late" integrations moved out of ScriptableUnityOptions - which is not getting called when initializing manually - into the initialization flow.

Note

One could point out the inconsistency how integrations get controlled and added, i.e. AnrIntegration, ScreenshotProcessor and ViewHierarchyProcessor. We could make changes to this but we'd require users to update from

options.AttachScreenshot = true;

to

options.AddEventProcessor(new ViewHierarchyEventProcessor(options));

which is not all that much better.

Comment on lines 230 to 244
if (options.AttachViewHierarchy)
{
options.AddEventProcessor(new ViewHierarchyEventProcessor(options));
}
if (options.AttachScreenshot)
{
options.AddEventProcessor(new ScreenshotEventProcessor(options));
}

if (!application.IsEditor && options.Il2CppLineNumberSupportEnabled && unityInfo is not null)
{
options.AddIl2CppExceptionProcessor(unityInfo);
}

HandlePlatformRestrictedOptions(options, unityInfo, application);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This got moved into SentryUnitySdk.Init to keep the SDKs behaviour consistent.

@@ -252,41 +246,6 @@ internal SentryUnityOptions ToSentryUnityOptions(bool isBuilding, ISentryUnityIn
return options;
}

internal void HandlePlatformRestrictedOptions(SentryUnityOptions options, ISentryUnityInfo? unityInfo, IApplication application)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same as above. Even if users call Init the SDK should make an effort not to crash the game.

Comment on lines -299 to -300
internal SentryUnityOptions(bool isBuilding, IApplication application, ISentryUnityInfo? unityInfo = null) :
this(SentryMonoBehaviour.Instance, application, isBuilding, unityInfo)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Got rid of a redundant internal constructor.

Comment on lines 66 to 76
internal static void AddIl2CppExceptionProcessor(this SentryUnityOptions options, ISentryUnityInfo unityInfo)
{
if (unityInfo.Il2CppMethods is not null)
{
options.AddExceptionProcessor(new UnityIl2CppEventExceptionProcessor(options, unityInfo));
}
else
{
options.DiagnosticLogger?.LogWarning("Failed to find required IL2CPP methods - Skipping line number support");
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved to Init.

Comment on lines 129 to 152
internal static void HandleWindowsPlayer(SentryUnitySdk unitySdk, SentryUnityOptions options)
{
// On Windows-Standalone, we disable cache dir in case multiple app instances run over the same path.
// Note: we cannot use a named Mutex, because Unity doesn't support it. Instead, we create a file with `FileShare.None`.
// https://forum.unity.com/threads/unsupported-internal-call-for-il2cpp-mutex-createmutex_internal-named-mutexes-are-not-supported.387334/
if (ApplicationAdapter.Instance.Platform is not RuntimePlatform.WindowsPlayer ||
options.CacheDirectoryPath is null)
{
return;
}

try
{
unitySdk._lockFile = new FileStream(Path.Combine(options.CacheDirectoryPath, "sentry-unity.lock"), FileMode.OpenOrCreate,
FileAccess.ReadWrite, FileShare.None);
}
catch (Exception ex)
{
options.DiagnosticLogger?.LogWarning("An exception was thrown while trying to " +
"acquire a lockfile on the config directory: .NET event cache will be disabled.", ex);
options.CacheDirectoryPath = null;
options.AutoSessionTracking = false;
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

To keep the Init more readable.

Comment on lines 165 to 176
if (!ApplicationAdapter.Instance.IsEditor &&
(SentryPlatformServices.UnityInfo?.IL2CPP ?? false) &&
options.Il2CppLineNumberSupportEnabled)
{
if (SentryPlatformServices.UnityInfo.Il2CppMethods is not null)
{
options.AddExceptionProcessor(new UnityIl2CppEventExceptionProcessor(options));
}
else
{
options.DiagnosticLogger?.LogWarning("Failed to find required IL2CPP methods - Skipping line number support");
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The IL2CPP Exception Processor is critical and "dangerous" as it calls into the IL2CPP backend and requires certain functions to be there. These functions change depending of Unity versions and are provided via IUnityInfo. As such, this does not get added by default but late during Init with extensive checks.

@bruno-garcia
Copy link
Member

This is a follow-up on #2227 as this was getting already kinda big.

"kinda" 😅

"Unity IL2CPP methods are not available.");

// We're throwing here but this should never happen. We're validating UnityInfo before adding the processor.
UnityInfo = SentryPlatformServices.UnityInfo
Copy link
Member

Choose a reason for hiding this comment

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

great! this was my only feedback in the other PR, validation that we're at the right state before going ahead

Also note that you copy a reference to use the same/consistent reference. This also means there's no path for a user to change these values after-the-fact.

But I understand that's the goal, and we then should follow this pattern when it makes sense. Instead of accessing the static mutable property in many places try to keep it to a minimum.

Base automatically changed from fix/initialization to main July 15, 2025 06:26

try
{
unitySdk._lockFile = new FileStream(Path.Combine(options.CacheDirectoryPath, "sentry-unity.lock"), FileMode.OpenOrCreate,
Copy link
Member

Choose a reason for hiding this comment

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

oh this looks odd. We're accessing a field from that instance in here? If that's internal name it LockFIle or something (Pascal Case)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants