Skip to content

Commit 9bc6522

Browse files
altunsercanMathijs-Bakker
authored andcommitted
Added failure check for async tasks
1 parent 9349961 commit 9bc6522

File tree

2 files changed

+82
-13
lines changed

2 files changed

+82
-13
lines changed

UnityProject/Assets/Plugins/Zenject/OptionalExtras/Async/Runtime/AsyncInject.cs

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,11 @@ public class AsyncInject<T> : AsyncInject
2929
public event Action Cancelled;
3030

3131
public bool HasResult { get; protected set; }
32+
public bool IsSuccessful { get; protected set; }
3233
public bool IsCancelled { get; protected set; }
3334
public bool IsFaulted { get; protected set; }
3435

35-
public bool IsCompleted => HasResult || IsCancelled || IsFaulted;
36+
public bool IsCompleted => IsSuccessful || IsCancelled || IsFaulted;
3637

3738
T _result;
3839
Task<T> task;
@@ -56,30 +57,60 @@ public void Cancel()
5657

5758
protected async void StartAsync(Func<CancellationToken, Task<T>> asyncMethod, CancellationToken token)
5859
{
59-
task = asyncMethod(token);
60-
await task;
61-
60+
try
61+
{
62+
task = asyncMethod(token);
63+
await task;
64+
}
65+
catch (AggregateException e)
66+
{
67+
HandleFaulted(e);
68+
return;
69+
}
70+
catch (Exception e)
71+
{
72+
HandleFaulted(new AggregateException(e));
73+
return;
74+
}
75+
6276
if (token.IsCancellationRequested)
6377
{
78+
HandleCancelled();
6479
return;
6580
}
6681

6782
if (task.IsCompleted)
6883
{
69-
_result = task.Result;
70-
HasResult = true;
71-
Completed?.Invoke(task.Result);
84+
HandleCompleted(task.Result);
7285
}else if (task.IsCanceled)
7386
{
74-
IsCancelled = true;
75-
Cancelled?.Invoke();
87+
HandleCancelled();
7688
}else if (task.IsFaulted)
7789
{
78-
IsFaulted = true;
79-
Faulted?.Invoke(task.Exception);
90+
HandleFaulted(task.Exception);
8091
}
8192
}
8293

94+
private void HandleCompleted(T result)
95+
{
96+
_result = result;
97+
HasResult = !result.Equals(default(T));
98+
IsSuccessful = true;
99+
Completed?.Invoke(result);
100+
}
101+
102+
private void HandleCancelled()
103+
{
104+
IsCancelled = true;
105+
Cancelled?.Invoke();
106+
}
107+
108+
private void HandleFaulted(AggregateException exception)
109+
{
110+
IsFaulted = true;
111+
Faulted?.Invoke(exception);
112+
}
113+
83114
public bool TryGetResult(out T result)
84115
{
85116
if (HasResult)

UnityProject/Assets/Plugins/Zenject/OptionalExtras/Async/Tests/Addressable/TestAddressable.cs

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,10 @@
33
using Zenject;
44
using System.Collections;
55
using System.Collections.Generic;
6-
using ModestTree;
76
using NUnit.Framework;
87
using UnityEngine;
98
using UnityEngine.TestTools;
109
using UnityEngine.AddressableAssets;
11-
using UnityEngine.ResourceManagement;
1210
using UnityEngine.ResourceManagement.AsyncOperations;
1311
using UnityEngine.ResourceManagement.ResourceLocations;
1412
using Assert = NUnit.Framework.Assert;
@@ -100,6 +98,46 @@ public IEnumerator TestAssetReferenceTMethod()
10098
Addressables.Release(asyncPrefab.AssetReferenceHandle);
10199
Assert.Pass();
102100
}
101+
102+
[UnityTest]
103+
[Timeout(10500)]
104+
public IEnumerator TestFailedLoad()
105+
{
106+
PreInstall();
107+
108+
Container.BindAsync<GameObject>().FromMethod(async () =>
109+
{
110+
FailedOperation failingOperation = new FailedOperation();
111+
var customHandle = Addressables.ResourceManager.StartOperation(failingOperation, default(AsyncOperationHandle));
112+
await customHandle.Task;
113+
114+
if (customHandle.Status == AsyncOperationStatus.Failed)
115+
{
116+
throw new Exception("Async operation failed", customHandle.OperationException);
117+
}
118+
119+
return customHandle.Result;
120+
}).AsCached();
121+
PostInstall();
122+
123+
yield return new WaitForEndOfFrame();
124+
125+
LogAssert.ignoreFailingMessages = true;
126+
AsyncInject<GameObject> asyncGameObj = Container.Resolve<AsyncInject<GameObject>>();
127+
LogAssert.ignoreFailingMessages = false;
128+
129+
Assert.IsFalse(asyncGameObj.HasResult);
130+
Assert.IsTrue(asyncGameObj.IsCompleted);
131+
Assert.IsTrue(asyncGameObj.IsFaulted);
132+
}
133+
134+
private class FailedOperation : AsyncOperationBase<GameObject>
135+
{
136+
protected override void Execute()
137+
{
138+
Complete(null, false, "Intentionally failed message");
139+
}
140+
}
103141

104142
private IEnumerator ValidateTestDependency()
105143
{

0 commit comments

Comments
 (0)