Exceptions are never reported when UniTask is executed without await and Forget()
See original GitHub issueAn exception that happens inside a UniTask is never reported, not even after GC.Collect, under specific conditions:
- the UniTask method is run without
await
andForget()
- the exception is thrown in the same frame the UniTask is launched
An example:
public class TestBehaviour : MonoBehaviour
{
private void Awake()
{
TestAsync();
}
private async UniTask TestAsync()
{
throw new Exception();
}
}
The exception will not be logged to the console even if I press GC.Collect in the UniTask Tracker window. However, if the exception is thrown in subsequent frames, everything is fine:
private async UniTask TestAsync()
{
await UniTask.NextFrame();
throw new Exception(); // logged after GC.Collect
}
The bug is unlikely to happen because usually there is a CS4014 warning that warns us the call is not awaited. However, when using async methods through interfaces, the warning is not reported, so you can forget to use either await
or Forget()
:
public interface ITestInterface
{
UniTask Test();
}
public class TestClass : ITestInterface
{
public async UniTask Test()
{
throw new Exception();
}
}
public class TestBehaviour : MonoBehaviour
{
private void Awake()
{
ITestInterface interfaceInstance = new TestClass();
interfaceInstance.Test(); // There is no CS4014 warning because there is no async keyword in the interface declaration.
}
}
So when you forget to put await
or Forget()
in such a case, it is a very big pain to debug it later because there is no sign of what went wrong.
Issue Analytics
- State:
- Created 2 years ago
- Reactions:2
- Comments:5 (5 by maintainers)
Top Results From Across the Web
Async Tasks, Cancellation, and Exceptions
Just without the exception. I always get a TaskCanceledException if I await the task returned. My guess would be that this is normal...
Read more >Suppressing/not logging exceptions from ThreadPool and ...
As you can see there are three exceptions thrown from background threads. From newly created thread and from thread pool. In "normal" ....
Read more >com.cysharp.unitask
Provides an efficient allocation free async/await integration for Unity. Struct based UniTask<T> and custom AsyncMethodBuilder to achieve zero allocation; Makes ...
Read more >Unity Async vs Coroutine
The time it takes to run UniTask.Yield() matches the coroutine and async counterparts. No alt text provided for this image. Here's where it...
Read more >Async in Unity (better or worse than coroutines?)
Async / Await is a C# scripting feature in Unity that allows you to execute part of a function asynchronously.
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Thanks. You are correct, I’m sorry to didn’t investigate. It would be better to change the
Exception ex;
field toExceptionHolder
.Destroying TestBehaviour doesn’t help, unfortunately, not even destroying the game object it is in