{"record":{"id":"088df0d2b1b63de4","repo":"Cysharp/UniTask","slug":"unitywebrequest-error","errorCode":null,"errorMessage":"unityWebRequest.error","messagePattern":"unityWebRequest\\.error","errorType":"exception","errorClass":"UnityWebRequestException","httpStatus":null,"severity":"error","filePath":"src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.cs","lineNumber":1018,"sourceCode":"                if (continuationAction != null)\n                {\n                    asyncOperation.completed -= continuationAction;\n                    continuationAction = null;\n                    var result = asyncOperation.webRequest;\n                    asyncOperation = null;\n                    if (result.IsError())\n                    {\n                        throw new UnityWebRequestException(result);\n                    }\n                    return result;\n                }\n                else\n                {\n                    var result = asyncOperation.webRequest;\n                    asyncOperation = null;\n                    if (result.IsError())\n                    {\n                        throw new UnityWebRequestException(result);\n                    }\n                    return result;\n                }\n            }\n\n            public void OnCompleted(Action continuation)\n            {\n                UnsafeOnCompleted(continuation);\n            }\n\n            public void UnsafeOnCompleted(Action continuation)\n            {\n                Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction);\n                continuationAction = PooledDelegate<AsyncOperation>.Create(continuation);\n                asyncOperation.completed += continuationAction;\n            }\n        }\n","sourceCodeStart":1000,"sourceCodeEnd":1036,"githubUrl":"https://github.com/Cysharp/UniTask/blob/ceac8d6946b1125fe782cd171fbcb245b567dbf9/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.cs#L1000-L1036","documentation":"Thrown by UnityWebRequestAsyncOperationAwaiter.GetResult() (line 1018) — the awaiter for `await unityWebRequestAsyncOperation` — when UnityWebRequest.IsError() returns true. IsError() maps to a connection error, protocol error (HTTP 4xx/5xx), or data-processing error (Unity 2020.2+) / isHttpError||isNetworkError (older). The failing request is wrapped in UnityWebRequestException, which exposes .Error, .ResponseCode, .Text (download body), and .ResponseHeaders; its Message is built from unityWebRequest.error plus the body text.","triggerScenarios":"Awaiting a UnityWebRequestAsyncOperation (or calling .ToUniTask() / .WithCancellation() on it) whose request failed: network unreachable, DNS failure, connection reset, request aborted on cancellation, HTTP 4xx/5xx response, or a download/upload handler data-processing error.","commonSituations":"Device offline or flaky network; wrong/unreachable URL; expired or missing auth token (401/403); server 5xx or CORS; self-signed/untrusted certificate; the request aborted because a CancellationToken fired (WithCancellation aborts via webRequest.Abort()).","solutions":["Wrap the await in try/catch(UnityWebRequestException) and branch on .ResponseCode/.Error.","For transient failures (ResponseCode == 0 / connection error), retry with backoff.","Pre-validate URL, headers, and auth before sending; refresh tokens on 401 rather than treating it as fatal.","Pass a CancellationToken via .WithCancellation() to abort hung requests and handle the resulting cancellation/error."],"exampleFix":"// before\nvar op = UnityWebRequest.Get(url).SendWebRequest();\nvar req = await op; // throws UnityWebRequestException on any error\n\n// after\ntry {\n    var op = UnityWebRequest.Get(url).SendWebRequest();\n    var req = await op;\n    var body = req.downloadHandler.text;\n} catch (UnityWebRequestException ex) {\n    Debug.LogWarning($\"{ex.ResponseCode} {ex.Error}\\n{ex.Text}\");\n}","handlingStrategy":"try-catch","validationCode":"// Pre-flight input checks (cannot prevent runtime network failures)\nif (string.IsNullOrWhiteSpace(url)) throw new ArgumentException(\"url required\", nameof(url));\nif (!Uri.TryCreate(url, UriKind.Absolute, out var uri)) throw new ArgumentException(\"invalid url\", nameof(url));","typeGuard":"bool IsWebError(Exception ex) => ex is UnityWebRequestException uwe\n    && (uwe.ResponseCode == 0\n        || (uwe.ResponseCode >= 400 && uwe.ResponseCode < 600));","tryCatchPattern":"try {\n    var op = UnityWebRequest.Get(url).SendWebRequest();\n    var req = await op;\n    // use req.downloadHandler.text\n} catch (UnityWebRequestException ex) {\n    // ex.ResponseCode==0 => connection/abort; 4xx/5xx => protocol error\n    if (ex.ResponseCode == 0) await RetryAsync();\n    else HandleHttpError(ex);\n}","preventionTips":["Always catch UnityWebRequestException around web awaits — a 'done' request is not a 'success' request.","Distinguish network/abort errors (ResponseCode == 0, Result.ConnectionError) from protocol errors (4xx/5xx) for retry vs. user-error handling.","Pass a CancellationToken and use .WithCancellation(ct) to abort hung requests, then handle the resulting OperationCanceledException/UnityWebRequestException.","Refresh auth tokens on 401 and retry once rather than surfacing the error to the user."],"tags":["network","unitywebrequest","http","unitask","unity"],"backgroundTag":null,"analyzedSha":"ceac8d6946b1125fe782cd171fbcb245b567dbf9","analyzedAt":"2026-08-13T19:16:39.025Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}