{"record":{"id":"c2d30c82280aaf25","repo":"JosefNemec/Playnite","slug":"result-error","errorCode":null,"errorMessage":"result.Error","messagePattern":"result\\.Error","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"source/Playnite/Services/BaseServicesClient.cs","lineNumber":40,"sourceCode":"            Timeout = new TimeSpan(0, 0, 60)\r\n        };\r\n\r\n        public BaseServicesClient(string endpoint, Version playniteVersion)\r\n        {\r\n            Endpoint = endpoint.TrimEnd('/');\r\n            HttpClient.DefaultRequestHeaders.Add(\"Playnite-Version\", playniteVersion.ToString(4));\r\n        }\r\n\r\n        public T ExecuteGetRequest<T>(string subUrl)\r\n        {\r\n            var url = Uri.EscapeUriString(Endpoint + subUrl);\r\n            var strResult = HttpClient.GetStringAsync(url).GetAwaiter().GetResult();\r\n            var result = Serialization.FromJson<ServicesResponse<T>>(strResult);\r\n\r\n            if (!string.IsNullOrEmpty(result.Error))\r\n            {\r\n                logger.Error(\"Service request error by proxy: \" + result.Error);\r\n                throw new Exception(result.Error);\r\n            }\r\n\r\n            return result.Data;\r\n        }\r\n\r\n        public T ExecutePostRequest<T>(string subUrl, string jsonContent)\r\n        {\r\n            var url = Uri.EscapeUriString(Endpoint + subUrl);\r\n            var content = new StringContent(jsonContent, Encoding.UTF8, \"application/json\");\r\n            var response = HttpClient.PostAsync(url, content).GetAwaiter().GetResult();\r\n            var strResult = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();\r\n            var result = Serialization.FromJson<ServicesResponse<T>>(strResult);\r\n\r\n            if (!string.IsNullOrEmpty(result.Error))\r\n            {\r\n                logger.Error(\"Service request error by proxy: \" + result.Error);\r\n                throw new Exception(result.Error);\r\n            }\r","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/JosefNemec/Playnite/blob/5911f4e964e628aa7a69c2030ab35101afa63067/source/Playnite/Services/BaseServicesClient.cs#L22-L58","documentation":"Thrown by BaseServicesClient.ExecuteGetRequest<T> when a GET to the Playnite services endpoint returns a ServicesResponse<T> whose Error field is non-empty. The proxy/server reported an error in its payload, so the client logs it and re-throws as a plain Exception carrying the server's message.","triggerScenarios":"ExecuteGetRequest hits Endpoint+subUrl, deserializes the JSON body into ServicesResponse<T>, and result.Error is non-empty at line 37. The server-side handler ran but failed (validation error, internal exception, rate limit, etc.).","commonSituations":"Addon/feature/patron lookup where the backend rejected the request (bad searchTerm, unknown addonId, DB error). Services proxy misconfigured or returning a 200-with-Error for upstream failures. Network returned an HTML error page that partially deserialized with Error set. Version header check server-side rejected the client.","solutions":["Inspect the logged message ('Service request error by proxy: ' + result.Error) and the server-side logs for the underlying cause.","Validate the subUrl and query parameters (e.g. searchTerm, addonId) before calling.","Confirm the Endpoint (ServicesUrl) and Playnite-Version header are correct for the target service.","If transient (rate limit, backend restart), retry after a short delay; otherwise report the server error text."],"exampleFix":"// before\nvar addons = client.ExecuteGetRequest<List<AddonManifest>>($\"/addons?type={type}&searchTerm={searchTerm}\".UrlEncode());\n\n// after — sanitize input and surface server error\nif (string.IsNullOrWhiteSpace(searchTerm)) throw new ArgumentException(nameof(searchTerm));\ntry { return client.ExecuteGetRequest<List<AddonManifest>>(...); }\ncatch (Exception ex) { logger.Error(ex, \"Addons lookup failed\"); throw; }","handlingStrategy":"try-catch","validationCode":"// Sanity-check inputs before the GET:\nif (string.IsNullOrWhiteSpace(subUrl)) throw new ArgumentException(nameof(subUrl));\n// (server-side Error cannot be pre-validated; rely on try/catch)","typeGuard":"static bool LooksLikeValidSubUrl(string s) => !string.IsNullOrWhiteSpace(s) && s.StartsWith(\"/\");","tryCatchPattern":"try { return client.ExecuteGetRequest<T>(subUrl); }\ncatch (Exception ex)\n{\n    logger.Error(ex, $\"GET {subUrl} failed\");\n    if (IsTransient(ex.Message)) { await Task.Delay(backoff); return client.ExecuteGetRequest<T>(subUrl); }\n    throw;\n}","preventionTips":["Validate query parameters before each GET.","Log and surface the server's Error text for diagnosis.","Add a transient-error retry with bounded backoff for rate-limit-style failures."],"tags":["network","services","http","client","playnite"],"backgroundTag":null,"analyzedSha":"5911f4e964e628aa7a69c2030ab35101afa63067","analyzedAt":"2026-08-13T17:38:25.713Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}