Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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

Large diffs are not rendered by default.

245 changes: 183 additions & 62 deletions samples/unity-of-bugs/Assets/Scenes/2_NativeSupport.unity

Large diffs are not rendered by default.

165 changes: 127 additions & 38 deletions samples/unity-of-bugs/Assets/Scenes/3_AdditionalSamples.unity

Large diffs are not rendered by default.

940 changes: 295 additions & 645 deletions samples/unity-of-bugs/Assets/Scenes/4_ThreadedSamples.unity

Large diffs are not rendered by default.

3,011 changes: 3,011 additions & 0 deletions samples/unity-of-bugs/Assets/Scenes/5_ForceCrashSamples.unity

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
using System.Collections;
using System.Threading;
using System.Threading;
using Sentry;
using Sentry.Unity;
using UnityEngine;

public class AdditionalButtons : MonoBehaviour
public class AdditionalSampleButtons : MonoBehaviour
{
public void SetUser()
{
// Setting the user on the scope makes sure the user is set on the context of all future events
SentrySdk.ConfigureScope(s =>
{
s.User = new SentryUser
Expand All @@ -20,7 +20,7 @@ public void SetUser()
Debug.Log("User set: ant");
}

class PlayerCharacter
private class PlayerCharacter
{
public string Name { get; set; }
public int Age { get; set; }
Expand All @@ -29,7 +29,9 @@ class PlayerCharacter

public void CaptureMessageWithContext()
{
SentrySdk.ConfigureScope(scope =>
// The context is freely customizable and allows you to add data specific to your game.
// The SDKs capture methods provide an optional scope that is only getting applied for that one specific event
SentrySdk.CaptureMessage("Capturing with player character context.", scope =>
{
scope.Contexts["character"] = new PlayerCharacter
{
Expand All @@ -38,30 +40,14 @@ public void CaptureMessageWithContext()
AttackType = "melee"
};
});

SentrySdk.CaptureMessage("Capturing with player character context.");
SentrySdk.ConfigureScope(scope => scope.Contexts = null);
}

public void CaptureMessageWithScreenshot() => StartCoroutine(CaptureScreenshot());

public void ApplicationNotResponding()
{
Debug.Log("Running Thread.Sleep() on the UI thread to trigger an ANR event.");
Thread.Sleep(6 * 1000); // ANR detection currently defaults to 5 seconds
Debug.Log("Thread.Sleep() finished.");
}

private IEnumerator CaptureScreenshot()
{
yield return new WaitForEndOfFrame();
SentrySdk.ConfigureScope(s =>
{
var screenshot = ScreenCapture.CaptureScreenshotAsTexture();
s.AddAttachment(screenshot.EncodeToJPG(), "screenshot.jpg");
});

SentrySdk.CaptureMessage("Captured a message with a screenshot attachment");
SentrySdk.ConfigureScope(scope => scope.ClearAttachments());
}
public void Assert() => UnityEngine.Assertions.Assert.IsTrue(false);
}
87 changes: 45 additions & 42 deletions samples/unity-of-bugs/Assets/Scripts/BugFarmButtons.cs
Original file line number Diff line number Diff line change
@@ -1,95 +1,98 @@
using System;
using System.Runtime.CompilerServices;
using Sentry;
using Sentry.Unity;
using UnityEngine;
using UnityEngine.Assertions;

public class BugFarmButtons : MonoBehaviour
{
private void Awake()
{
Debug.Log("Sample 🐛");
Debug.Log("The 🐛s awaken!");
}

private void Start()
{
Debug.Log("Sample Start 🦋");
// Log messages are getting captured as breadcrumbs
Debug.Log("Starting the 🦋-Farm");
Debug.LogWarning("Here come the bugs 🐞🦋🐛🐜🕷!");
}

public void AssertFalse() => Assert.AreEqual(true, false);

[MethodImpl(MethodImplOptions.NoInlining)]
public void ThrowNull() => throw new NullReferenceException();
public void ThrowUnhandledException()
{
Debug.Log("Throwing a unhandled 🕷 exception!");
DoSomeWorkHere();
}

public void ThrowExceptionAndCatch()
public void ThrowExceptionButCatch()
{
Debug.Log("Throwing an instance of 🐛 CustomException!");
Debug.Log("Throwing an exception but catching it! 🐜");

try
{
throw new CustomException("Custom bugs 🐛🐛🐛🐛.");
DoSomeWorkHere();
}
catch (Exception e)
{
SentrySdk.CaptureException(e);
}
}

public void ThrowNullAndCatch()
private void DoSomeWorkHere()
{
Debug.Log("Throwing 'null' and catching 🐜🐜🐜 it!");

try
if (CheckSomeFakeWork())
{
ThrowNull();
}
catch (Exception e)
{
SentrySdk.CaptureException(e);
DoSomeWorkThere();
}
}

public void CaptureMessage() => SentrySdk.CaptureMessage("🕷️🕷️🕷️ Spider message 🕷️🕷️🕷️🕷️");

// IL2CPP inlines this anyway :( - so we're adding some fake work to prevent the compiler from optimizing too much
[MethodImpl(MethodImplOptions.NoInlining)]
private void StackTraceExampleB()
private void DoSomeWorkThere()
{
var someWork = DateTime.Now.ToString();
if (someWork.Length > 0) // This condition will always be true but compiler can't be certain
if (CheckSomeFakeWork())
{
throw new InvalidOperationException("Exception from a lady beetle 🐞");
throw new CustomException("Exception from an exceptional lady beetle 🐞!");
}
}

// IL2CPP inlines this anyway :( - so we're adding some fake work to prevent the compiler from optimizing too much
[MethodImpl(MethodImplOptions.NoInlining)]
public void StackTraceExampleA()
public void CaptureMessage()
{
var someWork = DateTime.Now.ToString();
if (someWork.Length > 0) // This condition will always be true but compiler can't be certain
if (CheckSomeFakeWork())
{
StackTraceExampleB();
// Messages do not have a stacktrace attached by default. This is an opt-in feature.
// Note: That stack traces generated for message events are provided without line numbers. See known limitations
// https://docs.sentry.io/platforms/unity/troubleshooting/known-limitations/#line-numbers-missing-in-events-captured-through-debuglogerror-or-sentrysdkcapturemessage
SentrySdk.CaptureMessage("🕷️🕷️🕷️ Spider message 🕷️🕷️🕷️🕷️");
}
}

// IL2CPP inlines this anyway :( - so we're adding some fake work to prevent the compiler from optimizing too much
[MethodImpl(MethodImplOptions.NoInlining)]
public void LogError()
{
var someWork = DateTime.Now.ToString();
if (someWork.Length > 0) // This condition will always be true but compiler can't be certain
if (CheckSomeFakeWork())
{
// Error logs get captured as messages and do not have a stacktrace attached by default. This is an opt-in feature.
// Note: That stack traces generated for message events are provided without line numbers. See known limitations
// https://docs.sentry.io/platforms/unity/troubleshooting/known-limitations/#line-numbers-missing-in-events-captured-through-debuglogerror-or-sentrysdkcapturemessage
Debug.LogError("Debug.LogError() called");
}
}
}

public class CustomException : Exception
{
public CustomException(string message) : base(message)
public void LogException()
{
if (CheckSomeFakeWork())
{
// Error logs get captured as messages and do not have a stacktrace attached by default. This is an opt-in feature.
Debug.LogException(new NullReferenceException("Some bugs are harder to catch than others. 🦋"));
}
}

// NoInlining ends up being inlined through L2CPP anyway. :(
// We're checking some fake work here to prevent too aggressive optimization. That way, we can show off some proper
// stack traces that are closer to real-world bugs and events.
[MethodImpl(MethodImplOptions.NoInlining)]
private static bool CheckSomeFakeWork() => DateTime.Now.Ticks > 0; // Always true but not optimizable

private class CustomException : Exception
{
public CustomException(string message) : base(message)
{ }
}
}
11 changes: 11 additions & 0 deletions samples/unity-of-bugs/Assets/Scripts/ForceCrashButtons.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using UnityEngine;
using UnityEngine.Diagnostics;

public class ForceCrashButtons : MonoBehaviour
{
public void AccessViolation() => Utils.ForceCrash(ForcedCrashCategory.AccessViolation);
public void FatalError() => Utils.ForceCrash(ForcedCrashCategory.FatalError);
public void Abort() => Utils.ForceCrash(ForcedCrashCategory.Abort);
public void PureVirtualFunction() => Utils.ForceCrash(ForcedCrashCategory.PureVirtualFunction);
public void MonoAbort() => Utils.ForceCrash(ForcedCrashCategory.MonoAbort);
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions samples/unity-of-bugs/Assets/Scripts/SceneButtons.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ public class SceneButtons : MonoBehaviour
public void LoadNativeSupport() => SceneManager.LoadScene("2_NativeSupport");
public void LoadAdditionalSamples() => SceneManager.LoadScene("3_AdditionalSamples");
public void LoadThreadedSamples() => SceneManager.LoadScene("4_ThreadedSamples");
public void LoadForceCrashSamples() => SceneManager.LoadScene("5_ForceCrashSamples");

public void CloseGame()
{
Expand Down
130 changes: 90 additions & 40 deletions samples/unity-of-bugs/Assets/Scripts/ThreadingSamples.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using System.Threading.Tasks;
using Sentry.Unity;
using UnityEngine;
using UnityEngine.Assertions;

public class ThreadingSamples : MonoBehaviour
{
Expand All @@ -17,6 +16,88 @@ private void Start()
OnThreadingChange(0);
}

public void ThrowUnhandledException()
{
_executor(() =>
{
Debug.Log("Throwing a unhandled 🕷 exception!");
DoSomeWorkHere();
});
}

public void ThrowExceptionButCatch()
{
_executor(() =>
{
Debug.Log("Throwing an exception but catching it! 🐜");

try
{
DoSomeWorkHere();
}
catch (Exception e)
{
SentrySdk.CaptureException(e);
}
});
}

private void DoSomeWorkHere()
{
if (CheckSomeFakeWork())
{
DoSomeWorkThere();
}
}

private void DoSomeWorkThere()
{
if (CheckSomeFakeWork())
{
throw new CustomException("Exception from an exceptional lady beetle 🐞!");
}
}

public void CaptureMessage()
{
_executor(() =>
{
if (CheckSomeFakeWork())
{
// Messages do not have a stacktrace attached by default. This is an opt-in feature.
// Note: That stack traces generated for message events are provided without line numbers. See known limitations
// https://docs.sentry.io/platforms/unity/troubleshooting/known-limitations/#line-numbers-missing-in-events-captured-through-debuglogerror-or-sentrysdkcapturemessage
SentrySdk.CaptureMessage("🕷️🕷️🕷️ Spider message 🕷️🕷️🕷️🕷️");
}
});
}

public void LogError()
{
_executor(() =>
{
if (CheckSomeFakeWork())
{
// Error logs get captured as messages and do not have a stacktrace attached by default. This is an opt-in feature.
// Note: That stack traces generated for message events are provided without line numbers. See known limitations
// https://docs.sentry.io/platforms/unity/troubleshooting/known-limitations/#line-numbers-missing-in-events-captured-through-debuglogerror-or-sentrysdkcapturemessage
Debug.LogError("Debug.LogError() called");
}
});
}

public void LogException()
{
_executor(() =>
{
if (CheckSomeFakeWork())
{
// Error logs get captured as messages and do not have a stacktrace attached by default. This is an opt-in feature.
Debug.LogException(new NullReferenceException("Some bugs are harder to catch than others. 🦋"));
}
});
}

public void OnThreadingChange(int value)
{
string name;
Expand Down Expand Up @@ -56,46 +137,15 @@ public IEnumerator Coroutine(Action fn)
fn();
}

public void AssertFalse() => _executor(() => Assert.AreEqual(true, false));

// 'NoInlining' ends up being inlined through L2CPP anyway. :(
// We're checking some fake work here to prevent too aggressive optimization. That way, we can show off some proper
// stack traces that are closer to real-world bugs and events.
[MethodImpl(MethodImplOptions.NoInlining)]
public void ThrowNull() => _executor(() => throw null);

public void ThrowExceptionAndCatch() => _executor(() =>
{
Debug.Log("Throwing an instance of 🐛🧵🐛 CustomException!");

try
{
throw new CustomException("Custom bugs 🐛🧵🐛.");
}
catch (Exception e)
{
SentrySdk.CaptureException(e);
}
});
private static bool CheckSomeFakeWork() => DateTime.Now.Ticks > 0; // Always true but not optimizable

public void ThrowNullAndCatch() => _executor(() =>
private class CustomException : Exception
{
Debug.Log("Throwing 'null' and catching 🐜🧵🐜 it!");

try
{
ThrowNull();
}
catch (Exception e)
{
SentrySdk.CaptureException(e);
}
});

public void CaptureMessage() => _executor(() => SentrySdk.CaptureMessage("🕷️🧵️🕷️ Spider message 🕷️🧵️🕷️"));

[MethodImpl(MethodImplOptions.NoInlining)]
private void StackTraceExampleB() => throw new InvalidOperationException("Exception from a lady beetle 🐞🧵");

[MethodImpl(MethodImplOptions.NoInlining)]
public void StackTraceExampleA() => _executor(() => StackTraceExampleB());

public void LogError() => _executor(() => Debug.LogError("Debug.LogError() called"));
public CustomException(string message) : base(message)
{ }
}
}
Loading
Loading