{"record":{"id":"a180a36853491d96","repo":"Flow-Launcher/Flow.Launcher","slug":"error-code-response-statuscode-with-content","errorCode":null,"errorMessage":"Error code <{response.StatusCode}> with content <{content}> returned from <{url}>","messagePattern":"Error code <(.+?)> with content <(.+?)> returned from <(.+?)>","errorType":"exception","errorClass":"HttpRequestException","httpStatus":null,"severity":"error","filePath":"Flow.Launcher.Infrastructure/Http/Http.cs","lineNumber":166,"sourceCode":"        {\n            Log.Debug(ClassName, $\"Url <{url}>\");\n            return GetAsync(new Uri(url), token);\n        }\n\n        /// <summary>\n        /// \n        /// </summary>\n        /// <param name=\"url\"></param>\n        /// <param name=\"token\"></param>\n        /// <returns>The Http result as string. Null if cancellation requested</returns>\n        public static async Task<string> GetAsync([NotNull] Uri url, CancellationToken token = default)\n        {\n            Log.Debug(ClassName, $\"Url <{url}>\");\n            using var response = await client.GetAsync(url, token);\n            var content = await response.Content.ReadAsStringAsync(token);\n            if (response.StatusCode != HttpStatusCode.OK)\n            {\n                throw new HttpRequestException(\n                    $\"Error code <{response.StatusCode}> with content <{content}> returned from <{url}>\");\n            }\n\n            return content;\n        }\n\n        /// <summary>\n        /// Send a GET request to the specified Uri with an HTTP completion option and a cancellation token as an asynchronous operation.\n        /// </summary>\n        /// <param name=\"url\">The Uri the request is sent to.</param>\n        /// <param name=\"completionOption\">An HTTP completion option value that indicates when the operation should be considered completed.</param>\n        /// <param name=\"token\">A cancellation token that can be used by other objects or threads to receive notice of cancellation</param>\n        /// <returns></returns>\n        public static Task<Stream> GetStreamAsync([NotNull] string url,\n            CancellationToken token = default) => GetStreamAsync(new Uri(url), token);\n\n        /// <summary>\n        /// Send a GET request to the specified Uri with an HTTP completion option and a cancellation token as an asynchronous operation.","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/Flow-Launcher/Flow.Launcher/blob/7fc63b07bbaa10a0f0b2601487913fcba9ed24b0/Flow.Launcher.Infrastructure/Http/Http.cs#L148-L184","documentation":"Thrown as HttpRequestException from GetAsync(Uri) when response.StatusCode != HttpStatusCode.OK. Unlike DownloadAsync, the full response body is read first and embedded in the message, so the exception text includes both the status code, the URL, and the raw content — useful for diagnosing API errors that return JSON error payloads with a non-200 status.","triggerScenarios":"Calling GetAsync against a plugin-update/manifest endpoint that returns 404, 401, 500; an API gateway returns 200-shaped JSON with a 4xx status; the server returns 304 Not Modified (which != OK) when a conditional header is present; any 3xx redirect that HttpClient didn't auto-follow (e.g. to a disallowed scheme).","commonSituations":"Plugin marketplace/update API returning an error payload; user behind a proxy that injects a 407; expired auth token producing 401; rate-limited APIs returning 429; server-side validation errors returning 400 with a JSON body.","solutions":["Read the embedded content in the exception message — it usually contains the server's error description.","Confirm the URL is current and the endpoint accepts unauthenticated GET.","For 429, implement exponential backoff and respect Retry-After.","For 401/403, supply the required header/token via the request.","If the server legitimately returns non-OK with a usable body, change the check from '!= OK' to 'IsSuccessStatusCode' to accept all 2xx."],"exampleFix":"// before — rejects any non-200, even other 2xx\nif (response.StatusCode != HttpStatusCode.OK)\n    throw new HttpRequestException(...);\n\n// after — accept all 2xx success codes\nif (!response.IsSuccessStatusCode)\n    throw new HttpRequestException(\n        $\"{(int)response.StatusCode} from <{url}>: {content}\");","handlingStrategy":"try-catch","validationCode":"null","typeGuard":"null","tryCatchPattern":"try { return await Http.GetAsync(url, token); }\ncatch (HttpRequestException ex) { Log.Exception(ClassName, $\"GET {url} failed: {ex.Message}\", ex); throw; }","preventionTips":["Inspect the embedded content in the exception — it carries the server's error payload.","Use IsSuccessStatusCode instead of '== OK' if other 2xx codes are valid.","Add retry/backoff for 429 and 5xx responses.","Supply required auth/accept headers when the endpoint demands them."],"tags":["http","network","api","status-code"],"backgroundTag":null,"analyzedSha":"7fc63b07bbaa10a0f0b2601487913fcba9ed24b0","analyzedAt":"2026-08-13T14:54:20.914Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}