-
-
Notifications
You must be signed in to change notification settings - Fork 56
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
base: fix/initialization
Are you sure you want to change the base?
Changes from all commits
0b8a02f
7d0ffca
2ed2686
4379954
26567b3
24c4d94
70222d3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -136,7 +136,7 @@ internal SentryUnityOptions ToSentryUnityOptions(bool isBuilding, ISentryUnityIn | |
{ | ||
application ??= ApplicationAdapter.Instance; | ||
|
||
var options = new SentryUnityOptions(isBuilding, application, unityInfo) | ||
var options = new SentryUnityOptions(isBuilding, application, unityInfo, SentryMonoBehaviour.Instance) | ||
{ | ||
Enabled = Enabled, | ||
Dsn = Dsn, | ||
|
@@ -186,6 +186,12 @@ internal SentryUnityOptions ToSentryUnityOptions(bool isBuilding, ISentryUnityIn | |
PerformanceAutoInstrumentationEnabled = AutoAwakeTraces, | ||
}; | ||
|
||
// By default, the cacheDirectoryPath gets set on known platforms. The option is enabled by default | ||
if (!EnableOfflineCaching) | ||
{ | ||
options.CacheDirectoryPath = null; | ||
} | ||
|
||
if (!string.IsNullOrWhiteSpace(ReleaseOverride)) | ||
{ | ||
options.Release = ReleaseOverride; | ||
|
@@ -227,23 +233,11 @@ internal SentryUnityOptions ToSentryUnityOptions(bool isBuilding, ISentryUnityIn | |
// Without setting up here we might miss out on logs between option-loading (now) and Init - i.e. native configuration | ||
options.SetupUnityLogging(); | ||
|
||
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); | ||
Comment on lines
-230
to
-244
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This got moved into |
||
// ExceptionFilters are added by default to the options. | ||
HandleExceptionFilter(options); | ||
|
||
// The AnrDetectionIntegration is added by default. Since it is a ScriptableUnityOptions-only property we have to | ||
// remove the integration when creating the options through here | ||
if (!AnrDetectionEnabled) | ||
{ | ||
options.DisableAnrIntegration(); | ||
|
@@ -252,41 +246,6 @@ internal SentryUnityOptions ToSentryUnityOptions(bool isBuilding, ISentryUnityIn | |
return options; | ||
} | ||
|
||
internal void HandlePlatformRestrictedOptions(SentryUnityOptions options, ISentryUnityInfo? unityInfo, IApplication application) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above. Even if users call |
||
{ | ||
if (unityInfo?.IsKnownPlatform() == false) | ||
{ | ||
options.DisableFileWrite = true; | ||
|
||
// This is only provided on a best-effort basis for other than the explicitly supported platforms. | ||
if (options.BackgroundWorker is null) | ||
{ | ||
options.DiagnosticLogger?.LogDebug("Platform support for background thread execution is unknown: using WebBackgroundWorker."); | ||
options.BackgroundWorker = new WebBackgroundWorker(options, SentryMonoBehaviour.Instance); | ||
} | ||
|
||
// Disable offline caching regardless whether it was enabled or not. | ||
options.CacheDirectoryPath = null; | ||
if (EnableOfflineCaching) | ||
{ | ||
options.DiagnosticLogger?.LogDebug("Platform support for offline caching is unknown: disabling."); | ||
} | ||
|
||
// Requires file access, see https://github.com/getsentry/sentry-unity/issues/290#issuecomment-1163608988 | ||
if (options.AutoSessionTracking) | ||
{ | ||
options.DiagnosticLogger?.LogDebug("Platform support for automatic session tracking is unknown: disabling."); | ||
options.AutoSessionTracking = false; | ||
} | ||
|
||
return; | ||
} | ||
|
||
// Only assign the cache directory path if we're on a "known" platform. Accessing `Application.persistentDataPath` | ||
// implicitly creates a directory and leads to crashes i.e. on the Switch. | ||
options.CacheDirectoryPath = EnableOfflineCaching ? application.PersistentDataPath : null; | ||
} | ||
|
||
private void HandleExceptionFilter(SentryUnityOptions options) | ||
{ | ||
if (!options.FilterBadGatewayExceptions) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,7 @@ | |
using System.Text.RegularExpressions; | ||
using Sentry.Unity.Integrations; | ||
using Sentry.Extensibility; | ||
using Sentry.Unity.NativeUtils; | ||
using UnityEngine; | ||
using CompressionLevel = System.IO.Compression.CompressionLevel; | ||
|
||
|
@@ -294,39 +295,38 @@ internal string? DefaultUserId | |
|
||
internal List<string> SdkIntegrationNames { get; set; } = new(); | ||
|
||
public SentryUnityOptions() : this(false, ApplicationAdapter.Instance) { } | ||
|
||
internal SentryUnityOptions(bool isBuilding, IApplication application, ISentryUnityInfo? unityInfo = null) : | ||
this(SentryMonoBehaviour.Instance, application, isBuilding, unityInfo) | ||
Comment on lines
-299
to
-300
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Got rid of a redundant |
||
public SentryUnityOptions() : | ||
this(false, ApplicationAdapter.Instance, SentryPlatformServices.UnityInfo, SentryMonoBehaviour.Instance) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we access Can we then only get it from here? Once you do |
||
{ } | ||
|
||
// For testing | ||
internal SentryUnityOptions(SentryMonoBehaviour behaviour, IApplication application, bool isBuilding, ISentryUnityInfo? unityInfo = null) | ||
internal SentryUnityOptions(bool isBuilding, IApplication application, ISentryUnityInfo? unityInfo, | ||
SentryMonoBehaviour behaviour) | ||
{ | ||
// IL2CPP doesn't support Process.GetCurrentProcess().StartupTime | ||
DetectStartupTime = StartupTimeDetectionMode.Fast; | ||
|
||
this.AddInAppExclude("UnityEngine"); | ||
this.AddInAppExclude("UnityEditor"); | ||
AddInAppExclude("UnityEngine"); | ||
AddInAppExclude("UnityEditor"); | ||
var processor = new UnityEventProcessor(this); | ||
this.AddEventProcessor(processor); | ||
this.AddTransactionProcessor(processor); | ||
this.AddExceptionProcessor(new UnityExceptionProcessor()); | ||
|
||
this.AddIntegration(new UnityLogHandlerIntegration(this)); | ||
this.AddIntegration(new UnityApplicationLoggingIntegration()); | ||
this.AddIntegration(new StartupTracingIntegration()); | ||
this.AddIntegration(new AnrIntegration(behaviour)); | ||
this.AddIntegration(new UnityScopeIntegration(application, unityInfo)); | ||
this.AddIntegration(new UnityBeforeSceneLoadIntegration()); | ||
this.AddIntegration(new SceneManagerIntegration()); | ||
this.AddIntegration(new SceneManagerTracingIntegration()); | ||
this.AddIntegration(new SessionIntegration(behaviour)); | ||
this.AddIntegration(new TraceGenerationIntegration(behaviour)); | ||
|
||
this.AddExceptionFilter(new UnityBadGatewayExceptionFilter()); | ||
this.AddExceptionFilter(new UnityWebExceptionFilter()); | ||
this.AddExceptionFilter(new UnitySocketExceptionFilter()); | ||
AddEventProcessor(processor); | ||
AddTransactionProcessor(processor); | ||
AddExceptionProcessor(new UnityExceptionProcessor()); | ||
|
||
AddIntegration(new UnityLogHandlerIntegration(this)); | ||
AddIntegration(new UnityApplicationLoggingIntegration()); | ||
AddIntegration(new StartupTracingIntegration()); | ||
AddIntegration(new AnrIntegration(behaviour)); | ||
AddIntegration(new UnityScopeIntegration(application, unityInfo)); | ||
AddIntegration(new UnityBeforeSceneLoadIntegration()); | ||
AddIntegration(new SceneManagerIntegration()); | ||
AddIntegration(new SceneManagerTracingIntegration()); | ||
AddIntegration(new SessionIntegration(behaviour)); | ||
AddIntegration(new TraceGenerationIntegration(behaviour)); | ||
|
||
AddExceptionFilter(new UnityBadGatewayExceptionFilter()); | ||
AddExceptionFilter(new UnityWebExceptionFilter()); | ||
AddExceptionFilter(new UnitySocketExceptionFilter()); | ||
|
||
IsGlobalModeEnabled = true; | ||
|
||
|
@@ -363,6 +363,13 @@ internal SentryUnityOptions(SentryMonoBehaviour behaviour, IApplication applicat | |
{ LogType.Error, true}, | ||
{ LogType.Exception, true}, | ||
}; | ||
|
||
// Only assign the cache directory path if we're on a "known" platform. Accessing `Application.persistentDataPath` | ||
// implicitly creates a directory and leads to crashes i.e. on the Switch. | ||
if (unityInfo?.IsKnownPlatform() ?? false) | ||
{ | ||
CacheDirectoryPath = application.PersistentDataPath; | ||
} | ||
} | ||
|
||
public override string ToString() | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -63,18 +63,6 @@ internal static void SetupUnityLogging(this SentryUnityOptions options) | |
} | ||
} | ||
|
||
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"); | ||
} | ||
} | ||
Comment on lines
-66
to
-76
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Moved to |
||
|
||
/// <summary> | ||
/// Disables the capture of errors through <see cref="UnityLogHandlerIntegration"/>. | ||
/// </summary> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ | |
using System.Threading.Tasks; | ||
using Sentry.Extensibility; | ||
using Sentry.Unity.Integrations; | ||
using Sentry.Unity.NativeUtils; | ||
using UnityEngine; | ||
|
||
namespace Sentry.Unity; | ||
|
@@ -30,24 +31,11 @@ private SentryUnitySdk(SentryUnityOptions options) | |
|
||
MainThreadData.CollectData(); | ||
|
||
// On Standalone, we disable cache dir in case multiple app instances run over the same path. | ||
// Note: we cannot use a named Mutex, because Unit 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 RuntimePlatform.WindowsPlayer && options.CacheDirectoryPath is not null) | ||
{ | ||
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; | ||
} | ||
} | ||
// Some integrations are controlled through a flag and opt-in. Adding these integrations late so we have the | ||
// same behaviour whether we're self or manually initializing | ||
HandleLateIntegrations(options); | ||
HandlePlatformRestrictedOptions(options, SentryPlatformServices.UnityInfo); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. example where we take options and also access the static mutable public property There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. btw, I'm saying "static public mutable property" a lot because it's a thing you should be aware, I didn't read it btw just got the first link: https://www.reddit.com/r/learnprogramming/comments/7nzlec/why_are_mutable_static_variables_bad/ |
||
HandleWindowsPlayer(unitySdk, options); | ||
|
||
unitySdk._dotnetSdk = Sentry.SentrySdk.Init(options); | ||
|
||
|
@@ -137,4 +125,77 @@ public void CaptureFeedback(string message, string? email, string? name, bool ad | |
|
||
Sentry.SentrySdk.CurrentHub.CaptureFeedback(message, email, name, hint: hint); | ||
} | ||
|
||
internal static void HandleWindowsPlayer(SentryUnitySdk unitySdk, SentryUnityOptions options) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure this method is called. "Handle"? It seems it's "Setting Up"? or Initializing? It's being called by |
||
{ | ||
// 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; | ||
} | ||
} | ||
Comment on lines
+129
to
+152
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To keep the |
||
|
||
internal static void HandleLateIntegrations(SentryUnityOptions options) | ||
{ | ||
if (options.AttachViewHierarchy) | ||
{ | ||
options.AddEventProcessor(new ViewHierarchyEventProcessor(options)); | ||
} | ||
if (options.AttachScreenshot) | ||
{ | ||
options.AddEventProcessor(new ScreenshotEventProcessor(options)); | ||
} | ||
|
||
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"); | ||
} | ||
Comment on lines
+165
to
+176
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
} | ||
} | ||
|
||
internal static void HandlePlatformRestrictedOptions(SentryUnityOptions options, ISentryUnityInfo? unityInfo) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again method name is off, seems the guard is:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's a bit odd to see on the callsite:
Since you'd expect the guards to be outside the functions as the function names already 'declare' what they are supposed to be for. But this is all internal code so not worth splitting hairs 🙈 And I don't have a great suggestion on how to improve this other than maybe trying yet other method names "TryInit" or whatever |
||
{ | ||
if (unityInfo?.IsKnownPlatform() == false) | ||
{ | ||
options.DisableFileWrite = true; | ||
|
||
// Requires file access, see https://github.com/getsentry/sentry-unity/issues/290#issuecomment-1163608988 | ||
if (options.AutoSessionTracking) | ||
{ | ||
options.DiagnosticLogger?.LogDebug("Platform support for automatic session tracking is unknown: disabling."); | ||
options.AutoSessionTracking = false; | ||
} | ||
|
||
// This is only provided on a best-effort basis for other than the explicitly supported platforms. | ||
if (options.BackgroundWorker is null) | ||
{ | ||
options.DiagnosticLogger?.LogDebug("Platform support for background thread execution is unknown: using WebBackgroundWorker."); | ||
options.BackgroundWorker = new WebBackgroundWorker(options, SentryMonoBehaviour.Instance); | ||
} | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
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.