diff --git a/src/UniTask/Assets/Plugins/UniTask/Runtime/External/Addressables/AddressablesAsyncExtensions.cs b/src/UniTask/Assets/Plugins/UniTask/Runtime/External/Addressables/AddressablesAsyncExtensions.cs index 332870f..81baf37 100644 --- a/src/UniTask/Assets/Plugins/UniTask/Runtime/External/Addressables/AddressablesAsyncExtensions.cs +++ b/src/UniTask/Assets/Plugins/UniTask/Runtime/External/Addressables/AddressablesAsyncExtensions.cs @@ -22,13 +22,29 @@ namespace Cysharp.Threading.Tasks public static UniTask WithCancellation(this AsyncOperationHandle handle, CancellationToken cancellationToken) { - if (handle.IsDone) return UniTask.CompletedTask; + if (handle.IsDone) + { + if (handle.Status == AsyncOperationStatus.Failed) + { + return UniTask.FromException(handle.OperationException); + } + return UniTask.CompletedTask; + } + return new UniTask(AsyncOperationHandleWithCancellationSource.Create(handle, cancellationToken, out var token), token); } public static UniTask ToUniTask(this AsyncOperationHandle handle, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken)) { - if (handle.IsDone) return UniTask.CompletedTask; + if (handle.IsDone) + { + if (handle.Status == AsyncOperationStatus.Failed) + { + return UniTask.FromException(handle.OperationException); + } + return UniTask.CompletedTask; + } + return new UniTask(AsyncOperationHandleConfiguredSource.Create(handle, timing, progress, cancellationToken, out var token), token); } @@ -319,13 +335,28 @@ namespace Cysharp.Threading.Tasks public static UniTask WithCancellation(this AsyncOperationHandle handle, CancellationToken cancellationToken) { - if (handle.IsDone) return UniTask.FromResult(handle.Result); + if (handle.IsDone) + { + if (handle.Status == AsyncOperationStatus.Failed) + { + return UniTask.FromException(handle.OperationException); + } + return UniTask.FromResult(handle.Result); + } return new UniTask(AsyncOperationHandleWithCancellationSource.Create(handle, cancellationToken, out var token), token); } public static UniTask ToUniTask(this AsyncOperationHandle handle, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken)) { - if (handle.IsDone) return UniTask.FromResult(handle.Result); + if (handle.IsDone) + { + if (handle.Status == AsyncOperationStatus.Failed) + { + return UniTask.FromException(handle.OperationException); + } + return UniTask.FromResult(handle.Result); + } + return new UniTask(AsyncOperationHandleConfiguredSource.Create(handle, timing, progress, cancellationToken, out var token), token); } diff --git a/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.cs b/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.cs index c5cfbc2..6799a9c 100644 --- a/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.cs +++ b/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.cs @@ -1189,14 +1189,28 @@ namespace Cysharp.Threading.Tasks public static UniTask WithCancellation(this UnityWebRequestAsyncOperation asyncOperation, CancellationToken cancellationToken) { Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); - if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.webRequest); + if (asyncOperation.isDone) + { + if (asyncOperation.webRequest.IsError()) + { + return UniTask.FromException(new UnityWebRequestException(asyncOperation.webRequest)); + } + return UniTask.FromResult(asyncOperation.webRequest); + } return new UniTask(UnityWebRequestAsyncOperationWithCancellationSource.Create(asyncOperation, cancellationToken, out var token), token); } public static UniTask ToUniTask(this UnityWebRequestAsyncOperation asyncOperation, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken)) { Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); - if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.webRequest); + if (asyncOperation.isDone) + { + if (asyncOperation.webRequest.IsError()) + { + return UniTask.FromException(new UnityWebRequestException(asyncOperation.webRequest)); + } + return UniTask.FromResult(asyncOperation.webRequest); + } return new UniTask(UnityWebRequestAsyncOperationConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, out var token), token); } diff --git a/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.tt b/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.tt index d5cac19..aa12b5a 100644 --- a/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.tt +++ b/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.tt @@ -16,6 +16,7 @@ Func ToUniTaskReturnType = x => (x == "void") ? "UniTask" : $"UniTask<{x}>"; Func ToIUniTaskSourceReturnType = x => (x == "void") ? "IUniTaskSource" : $"IUniTaskSource<{x}>"; + Func<(string typeName, string returnType, string returnField), bool> IsUnityWebRequest = x => x.returnType == "UnityWebRequest"; Func<(string typeName, string returnType, string returnField), bool> IsVoid = x => x.returnType == "void"; #> #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member @@ -34,7 +35,7 @@ namespace Cysharp.Threading.Tasks public static partial class UnityAsyncExtensions { <# foreach(var t in types) { #> -<# if(t.returnType == "UnityWebRequest") { #> +<# if(IsUnityWebRequest(t)) { #> #if ENABLE_UNITYWEBREQUEST <# } #> #region <#= t.typeName #> @@ -48,14 +49,36 @@ namespace Cysharp.Threading.Tasks public static <#= ToUniTaskReturnType(t.returnType) #> WithCancellation(this <#= t.typeName #> asyncOperation, CancellationToken cancellationToken) { Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); +<# if(IsUnityWebRequest(t)) { #> + if (asyncOperation.isDone) + { + if (asyncOperation.webRequest.IsError()) + { + return UniTask.FromException(new UnityWebRequestException(asyncOperation.webRequest)); + } + return UniTask.FromResult(asyncOperation.webRequest); + } +<# } else { #> if (asyncOperation.isDone) return <#= IsVoid(t) ? "UniTask.CompletedTask" : $"UniTask.FromResult(asyncOperation.{t.returnField})" #>; +<# } #> return new <#= ToUniTaskReturnType(t.returnType) #>(<#= t.typeName #>WithCancellationSource.Create(asyncOperation, cancellationToken, out var token), token); } public static <#= ToUniTaskReturnType(t.returnType) #> ToUniTask(this <#= t.typeName #> asyncOperation, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken)) { Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); +<# if(IsUnityWebRequest(t)) { #> + if (asyncOperation.isDone) + { + if (asyncOperation.webRequest.IsError()) + { + return UniTask.FromException(new UnityWebRequestException(asyncOperation.webRequest)); + } + return UniTask.FromResult(asyncOperation.webRequest); + } +<# } else { #> if (asyncOperation.isDone) return <#= IsVoid(t) ? "UniTask.CompletedTask" : $"UniTask.FromResult(asyncOperation.{t.returnField})" #>; +<# } #> return new <#= ToUniTaskReturnType(t.returnType) #>(<#= t.typeName #>ConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, out var token), token); } @@ -81,7 +104,7 @@ namespace Cysharp.Threading.Tasks <# if (!IsVoid(t)) { #> var result = <#= $"asyncOperation.{t.returnField}" #>; asyncOperation = null; -<# if(t.returnType == "UnityWebRequest") { #> +<# if(IsUnityWebRequest(t)) { #> if (result.IsError()) { throw new UnityWebRequestException(result); @@ -97,7 +120,7 @@ namespace Cysharp.Threading.Tasks <# if (!IsVoid(t)) { #> var result = <#= $"asyncOperation.{t.returnField}" #>; asyncOperation = null; -<# if(t.returnType == "UnityWebRequest") { #> +<# if(IsUnityWebRequest(t)) { #> if (result.IsError()) { throw new UnityWebRequestException(result); @@ -182,7 +205,7 @@ namespace Cysharp.Threading.Tasks else { completed = true; -<# if(t.returnType == "UnityWebRequest") { #> +<# if(IsUnityWebRequest(t)) { #> var result = asyncOperation.webRequest; if (result.IsError()) { @@ -240,7 +263,7 @@ namespace Cysharp.Threading.Tasks if (cancellationToken.IsCancellationRequested) { completed = true; -<# if(t.returnType == "UnityWebRequest") { #> +<# if(IsUnityWebRequest(t)) { #> asyncOperation.webRequest.Abort(); <# } #> core.TrySetCanceled(cancellationToken); @@ -347,7 +370,7 @@ namespace Cysharp.Threading.Tasks { if (cancellationToken.IsCancellationRequested) { -<# if(t.returnType == "UnityWebRequest") { #> +<# if(IsUnityWebRequest(t)) { #> asyncOperation.webRequest.Abort(); <# } #> core.TrySetCanceled(cancellationToken); @@ -361,7 +384,7 @@ namespace Cysharp.Threading.Tasks if (asyncOperation.isDone) { -<# if(t.returnType == "UnityWebRequest") { #> +<# if(IsUnityWebRequest(t)) { #> if (asyncOperation.webRequest.IsError()) { core.TrySetException(new UnityWebRequestException(asyncOperation.webRequest)); @@ -391,7 +414,7 @@ namespace Cysharp.Threading.Tasks } #endregion -<# if(t.returnType == "UnityWebRequest") { #> +<# if(IsUnityWebRequest(t)) { #> #endif <# } #>