JosefNemec/Playnite · error · Exception
result.Error
Error message
result.Error
What it means
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.
Source
Thrown at source/Playnite/Services/BaseServicesClient.cs:40
Timeout = new TimeSpan(0, 0, 60)
};
public BaseServicesClient(string endpoint, Version playniteVersion)
{
Endpoint = endpoint.TrimEnd('/');
HttpClient.DefaultRequestHeaders.Add("Playnite-Version", playniteVersion.ToString(4));
}
public T ExecuteGetRequest<T>(string subUrl)
{
var url = Uri.EscapeUriString(Endpoint + subUrl);
var strResult = HttpClient.GetStringAsync(url).GetAwaiter().GetResult();
var result = Serialization.FromJson<ServicesResponse<T>>(strResult);
if (!string.IsNullOrEmpty(result.Error))
{
logger.Error("Service request error by proxy: " + result.Error);
throw new Exception(result.Error);
}
return result.Data;
}
public T ExecutePostRequest<T>(string subUrl, string jsonContent)
{
var url = Uri.EscapeUriString(Endpoint + subUrl);
var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");
var response = HttpClient.PostAsync(url, content).GetAwaiter().GetResult();
var strResult = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
var result = Serialization.FromJson<ServicesResponse<T>>(strResult);
if (!string.IsNullOrEmpty(result.Error))
{
logger.Error("Service request error by proxy: " + result.Error);
throw new Exception(result.Error);
}
View on GitHub (pinned to 5911f4e964)
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.
Example fix
// before
var addons = client.ExecuteGetRequest<List<AddonManifest>>($"/addons?type={type}&searchTerm={searchTerm}".UrlEncode());
// after — sanitize input and surface server error
if (string.IsNullOrWhiteSpace(searchTerm)) throw new ArgumentException(nameof(searchTerm));
try { return client.ExecuteGetRequest<List<AddonManifest>>(...); }
catch (Exception ex) { logger.Error(ex, "Addons lookup failed"); throw; } Defensive patterns
Strategy: try-catch
Validate before calling
// Sanity-check inputs before the GET: if (string.IsNullOrWhiteSpace(subUrl)) throw new ArgumentException(nameof(subUrl)); // (server-side Error cannot be pre-validated; rely on try/catch)
Type guard
static bool LooksLikeValidSubUrl(string s) => !string.IsNullOrWhiteSpace(s) && s.StartsWith("/"); Try / catch
try { return client.ExecuteGetRequest<T>(subUrl); }
catch (Exception ex)
{
logger.Error(ex, $"GET {subUrl} failed");
if (IsTransient(ex.Message)) { await Task.Delay(backoff); return client.ExecuteGetRequest<T>(subUrl); }
throw;
} Prevention
- 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.
When it happens
Trigger: 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.).
Common situations: 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.
Related errors
- result.Error
- Failed to download string from all mirrors.
- Failed to download file from all mirrors.
- Failed to download update file.
- Failed to download update manifest.
AI-assisted analysis of JosefNemec/Playnite@5911f4e964 (2026-08-13).
Data as JSON: /api/errors/c2d30c82280aaf25.
Report an issue: GitHub.