sentry-unity: Error sending when exception thrown in new thread (callbacks also not on unity main thread when this happens)
Environment
How do you use Sentry? Sentry SaaS (sentry.io)
Which SDK and version? Sentry Unity 0.8.0
Steps to Reproduce
Initialize sdk
SentryUnity.Init(o =>
{
o.Dsn = "XXXX";
// Useful when setting things up to see the SDK logs in the Unity console.
o.Debug = true;
o.StackTraceMode = StackTraceMode.Enhanced;
o.EnableLogDebouncing = true;
o.AndroidNativeSupportEnabled = true;
o.IosNativeSupportEnabled = true;
o.TracesSampleRate = UnityEngine.Debug.isDebugBuild ? 1 : 0.01f;
});
Throw an exception from a thread that isn’t the unity main thread
new Thread(() => throw new System.Exception("This is a test exception from another thread.")).Start()
Expected Result
No error, BeforeSend and other callbacks should be running on main thread so I can easily add a screenshot or other data from non thread safe areas.
Actual Result
Throws an error but also seems to run all callbacks off the main thread so I can’t use unity engine code when applying tags or attachments (i’ve removed all callback code for this test, perhaps this is two bugs).
Sentry: (Error) Failed to send cached envelope: C:/Users/David/AppData/LocalLow/ODD Games/MTD\Sentry\F187FFF4B6258D70B60D1537BB1C9F2AF2C703A1\__processing\1639566925_-1552_cc380117b5b34bd2a94c3cff3b94e2c4_390037632.envelope, retrying after a delay. System.Threading.Tasks.TaskCanceledException: A task was canceled.
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x00026] in <695d1cc93cca45069c528c15c9fdd749>:0
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <695d1cc93cca45069c528c15c9fdd749>:0
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <695d1cc93cca45069c528c15c9fdd749>:0
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[TResult].GetResult () [0x00000] in <695d1cc93cca45069c528c15c9fdd749>:0
at Sentry.Internal.Extensions.StreamExtensions+<ReadAllBytesAsync>d__0.MoveNext () [0x00102] in <ed2ef74d8b9944589c9227e32ae1d01d>:0
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <695d1cc93cca45069c528c15c9fdd749>:0
at System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore`1[TResult].GetResult (System.Int16 token) [0x0001f] in <d609ec26398e4c019208034a5926e641>:0
at Sentry.Internal.Extensions.StreamExtensions+<ReadAllBytesAsync>d__0.System.Threading.Tasks.Sources.IValueTaskSource<System.Boolean>.GetResult (System.Int16 token) [0x00000] in <ed2ef74d8b9944589c9227e32ae1d01d>:0
at Sentry.Protocol.Envelopes.EnvelopeItem+<DeserializeAsync>d__30.MoveNext () [0x001dc] in <ed2ef74d8b9944589c9227e32ae1d01d>:0
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <695d1cc93cca45069c528c15c9fdd749>:0
at Sentry.Protocol.Envelopes.EnvelopeItem+<DeserializeAsync>d__30.MoveNext () [0x0027b] in <ed2ef74d8b9944589c9227e32ae1d01d>:0
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <695d1cc93cca45069c528c15c9fdd749>:0
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0001a] in <695d1cc93cca45069c528c15c9fdd749>:0
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <695d1cc93cca45069c528c15c9fdd749>:0
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <695d1cc93cca45069c528c15c9fdd749>:0
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[TResult].GetResult () [0x00000] in <695d1cc93cca45069c528c15c9fdd749>:0
at Sentry.Protocol.Envelopes.Envelope+<DeserializeAsync>d__20.MoveNext () [0x00105] in <ed2ef74d8b9944589c9227e32ae1d01d>:0
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <695d1cc93cca45069c528c15c9fdd749>:0
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0001a] in <695d1cc93cca45069c528c15c9fdd749>:0
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <695d1cc93cca45069c528c15c9fdd749>:0
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <695d1cc93cca45069c528c15c9fdd749>:0
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[TResult].GetResult () [0x00000] in <695d1cc93cca45069c528c15c9fdd749>:0
at Sentry.Internal.Http.CachingTransport+<InnerProcessCacheAsync>d__15.MoveNext () [0x00094] in <ed2ef74d8b9944589c9227e32ae1d01d>:0
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <695d1cc93cca45069c528c15c9fdd749>:0
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0001a] in <695d1cc93cca45069c528c15c9fdd749>:0
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <695d1cc93cca45069c528c15c9fdd749>:0
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <695d1cc93cca45069c528c15c9fdd749>:0
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable+ConfiguredTaskAwaiter.GetResult () [0x00000] in <695d1cc93cca45069c528c15c9fdd749>:0
at Sentry.Internal.Http.CachingTransport+<ProcessCacheAsync>d__14.MoveNext () [0x0011e] in <ed2ef74d8b9944589c9227e32ae1d01d>:0
UnityEngine.Debug:LogError (object)
Sentry.Unity.UnityLogger:Log (Sentry.SentryLevel,string,System.Exception,object[]) (at /Users/runner/work/sentry-unity/sentry-unity/src/Sentry.Unity/UnityLogger.cs:47)
Sentry.Extensibility.DiagnosticLoggerExtensions:LogIfEnabled<string> (Sentry.Extensibility.IDiagnosticLogger,Sentry.SentryLevel,System.Exception,string,string)
Sentry.Extensibility.DiagnosticLoggerExtensions:LogError<string> (Sentry.SentryOptions,string,System.Exception,string)
Sentry.Internal.Http.CachingTransport/<ProcessCacheAsync>d__14:MoveNext ()
System.Runtime.CompilerServices.AsyncTaskMethodBuilder:SetException (System.Exception)
Sentry.Internal.Http.CachingTransport/<InnerProcessCacheAsync>d__15:MoveNext ()
System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<Sentry.Protocol.Envelopes.Envelope>:SetException (System.Exception)
Sentry.Protocol.Envelopes.Envelope/<DeserializeAsync>d__20:MoveNext ()
System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<Sentry.Protocol.Envelopes.EnvelopeItem>:SetException (System.Exception)
Sentry.Protocol.Envelopes.EnvelopeItem/<DeserializeAsync>d__30:MoveNext ()
System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<Sentry.Protocol.Envelopes.ISerializable>:SetResult (Sentry.Protocol.Envelopes.ISerializable)
Sentry.Protocol.Envelopes.EnvelopeItem/<DeserializePayloadAsync>d__29:MoveNext ()
System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<byte[]>:SetResult (byte[])
Sentry.Internal.Extensions.StreamExtensions/<ReadByteChunkAsync>d__1:MoveNext ()
System.Threading._ThreadPoolWaitCallback:PerformWaitCallback ()
edit by @vaind: wrap the stacktrace in a code block
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 16 (5 by maintainers)
I’ve added additional samples (& support for
LogError()/LogException()in background threads) in #673.For this issue, with the current understanding, my suggestion would be to keep
BeforeSendas is, i.e. being called from all threads. The issues it may cause if user implementation ofBeforeSenduses non-thread-safe APIs should be resolved by the user, while we could explicitly point this out in the docs.