{"record":{"id":"87f4e7e9506903ae","repo":"NickeManarin/ScreenToGif","slug":"errordescriptor-error-errordescriptor-message","errorCode":null,"errorMessage":"{errorDescriptor.Error}, {errorDescriptor.Message}, {errorDescriptor.Description}","messagePattern":"\\{errorDescriptor\\.Error\\}, \\{errorDescriptor\\.Message\\}, \\{errorDescriptor\\.Description\\}","errorType":"exception","errorClass":"UploadException","httpStatus":null,"severity":"error","filePath":"ScreenToGif/Cloud/YandexDisk.cs","lineNumber":78,"sourceCode":"        {\n            var request = new HttpRequestMessage(HttpMethod.Get, url)\n            {\n                Headers =\n                {\n                    {HttpRequestHeader.Authorization.ToString(), \"OAuth \" + preset.OAuthToken}\n                }\n            };\n\n            string responseBody;\n            using (var response = await client.SendAsync(request, cancellationToken))\n            {\n                responseBody = await response.Content.ReadAsStringAsync(cancellationToken);\n            }\n                \n            var errorDescriptor = Serializer.Deserialize<ErrorDescriptor>(responseBody);\n\n            if (errorDescriptor.Error != null)\n                throw new UploadException($\"{errorDescriptor.Error}, {errorDescriptor.Message}, {errorDescriptor.Description}\");\n\n            return Serializer.Deserialize<T>(responseBody);\n        }\n    }\n\n    private async Task PutAsync(YandexPreset preset, string url, HttpContent content, CancellationToken cancellationToken)\n    {\n        var handler = new HttpClientHandler\n        {\n            Proxy = WebHelper.GetProxy(),\n            PreAuthenticate = true,\n            UseDefaultCredentials = false,\n        };\n\n        using (var client = new HttpClient(handler))\n        {\n            var request = new HttpRequestMessage(HttpMethod.Put, url)\n            {","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/NickeManarin/ScreenToGif/blob/a4d0a67c2131cd048ceec86cd40afc2f1a06f2fd/ScreenToGif/Cloud/YandexDisk.cs#L60-L96","documentation":"Inside GetAsync<T>, the response body is first deserialized as an ErrorDescriptor; if its Error field is non-null, UploadException is thrown carrying the Yandex-provided error/message/description triple verbatim. This is the user-facing passthrough of any Yandex Disk REST API failure.","triggerScenarios":"Any Yandex cloud-api.yandex.net response containing a JSON 'error' field: 401 unauthorized (bad OAuth token), 406 invalid field, 413 file too large, 507 disk full, rate limiting, or ' DiskResourcePathNotFoundError'. The HTTP status itself is not checked — only the body's error field.","commonSituations":"Expired or revoked OAuth token; Yandex Disk quota exceeded (507 disk full); upload path collisions or forbidden characters; rate-limit response; region/network returned a Yandex-formatted error JSON.","solutions":["Re-authorize Yandex if the message indicates unauthorized/invalid token.","Free up Yandex Disk space if the message indicates DiskFull / quota exceeded.","Surface the triple (error, message, description) directly to the user rather than the generic label.","Add an HttpStatusCode check on response.StatusCode before deserializing, so non-200 responses are handled explicitly."],"exampleFix":"// before\nif (errorDescriptor.Error != null)\n    throw new UploadException($\"{errorDescriptor.Error}, {errorDescriptor.Message}, {errorDescriptor.Description}\");\n\n// after\nif ((int)response.StatusCode >= 400 || errorDescriptor.Error != null)\n    throw new UploadException($\"Yandex {errorDescriptor.Error ?? response.StatusCode.ToString()}: {errorDescriptor.Message}. {errorDescriptor.Description}\");","handlingStrategy":"try-catch","validationCode":"// Pre-flight: token must be present and quota assumed available\nvar yp = preset as YandexPreset;\nif (string.IsNullOrWhiteSpace(yp?.OAuthToken)) /* prompt re-auth */","typeGuard":"// n/a — error is data-driven, not type-driven","tryCatchPattern":"try { return await cloud.UploadFileAsync(preset, path, token); }\ncatch (UploadException ex) when (ex.Message.Contains(\"unauthorized\") || ex.Message.Contains(\"UnauthorizedError\"))\n{ /* refresh OAuth token, retry once */ }\ncatch (UploadException ex) when (ex.Message.Contains(\"DiskFull\"))\n{ /* surface quota message to user */ }","preventionTips":["Check HTTP status code explicitly in GetAsync instead of relying solely on the body's error field.","Surface the Yandex error triple verbatim to the user.","Refresh the OAuth token on a schedule to avoid unauthorized errors."],"tags":["yandex-disk","cloud-upload","network","api-error"],"backgroundTag":null,"analyzedSha":"a4d0a67c2131cd048ceec86cd40afc2f1a06f2fd","analyzedAt":"2026-08-13T11:12:06.147Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}