{"record":{"id":"37c9e2dde0bb2712","repo":"NickeManarin/ScreenToGif","slug":"empty-response-from-server-when-getting-language-c-37c9e2","errorCode":null,"errorMessage":"Empty response from server when getting language codes","messagePattern":"Empty response from server when getting language codes","errorType":"exception","errorClass":"WebException","httpStatus":null,"severity":"warning","filePath":"ScreenToGif/Windows/Other/Localization.xaml.cs","lineNumber":416,"sourceCode":"    }\n\n    private async Task<IEnumerable<string>> GetLanguageCodesAsync()\n    {\n        var path = await GetLanguageCodesPathAsync();\n\n        if (string.IsNullOrEmpty(path))\n            throw new WebException(\"Can't get language codes. Path to language codes is null\");\n\n        var request = (HttpWebRequest)WebRequest.Create(path);\n        request.UserAgent = \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393\";\n        request.Proxy = WebHelper.GetProxy();\n\n        var response = (HttpWebResponse)await request.GetResponseAsync();\n\n        using (var resultStream = response.GetResponseStream())\n        {\n            if (resultStream == null)\n                throw new WebException(\"Empty response from server when getting language codes\");\n\n            using (var reader = new StreamReader(resultStream))\n            {\n                var result = await reader.ReadToEndAsync();\n\n                var jsonReader = JsonReaderWriterFactory.CreateJsonReader(Encoding.UTF8.GetBytes(result),\n                    new System.Xml.XmlDictionaryReaderQuotas());\n\n                var json = await Task<XElement>.Factory.StartNew(() => XElement.Load(jsonReader));\n                var languages = json.Elements();\n\n                return await Task.Factory.StartNew(() => languages.Where(x => x.XPathSelectElement(\"defs\")?.Value != \"0\").Select(x => x.XPathSelectElement(\"lang\")?.Value));\n            }\n        }\n    }\n\n    private async Task<string> GetLanguageCodesPathAsync()\n    {","sourceCodeStart":398,"sourceCodeEnd":434,"githubUrl":"https://github.com/NickeManarin/ScreenToGif/blob/a4d0a67c2131cd048ceec86cd40afc2f1a06f2fd/ScreenToGif/Windows/Other/Localization.xaml.cs#L398-L434","documentation":"A WebException thrown inside GetLanguageCodesAsync after the second HTTP request (to the resolved language-codes path) succeeds with an HttpWebResponse but response.GetResponseStream() returns null. The guard fires before reading the stream, treating a null stream as an unrecoverable 'empty response from server'. In practice GetResponseStream rarely returns null for a valid HttpWebResponse, so this path is an edge case for broken proxies/streaming transports.","triggerScenarios":"GetResponseAsync() returned a non-null HttpWebResponse (no throw), but GetResponseStream() evaluated to null. This can happen with a malformed chunked-encoding response, a transparent proxy that closed the body, a 2xx with Content-Length 0 that some implementations surface as a null stream, or a custom WebRequest descendant returning null.","commonSituations":"A corporate/transparent proxy stripping the response body; the datahub.io CDN returned an empty 200 with no body; a transient TLS/connection close where the response headers arrived but the body stream could not be constructed; custom proxy via WebHelper.GetProxy misbehaving.","solutions":["Check HTTP status code before reading: if ((int)response.StatusCode >= 400) handle the error rather than assuming a body exists.","Retry the request once — null streams are typically transient transport/proxy issues.","Inspect WebHelper.GetProxy() configuration; a misconfigured proxy can strip bodies.","Verify the resolved language-codes path URL (from GetLanguageCodesPathAsync) is reachable and returns JSON in a browser/curl.","Fall back to the bundled hardcoded language code list (the GetSomething fallback near line 380) when the network path fails."],"exampleFix":"// before\nvar response = (HttpWebResponse)await request.GetResponseAsync();\nusing (var resultStream = response.GetResponseStream())\n{\n    if (resultStream == null)\n        throw new WebException(\"Empty response from server when getting language codes\");\n\n// after: check status + null-safe read with fallback\nvar response = (HttpWebResponse)await request.GetResponseAsync();\nusing (var resultStream = response.GetResponseStream())\n{\n    if (resultStream == null || response.ContentLength == 0)\n    {\n        LogWriter.Log($\"Empty language-codes body. Status: {response.StatusCode}, URL: {path}\");\n        return Enumerable.Empty<string>(); // caller falls back to bundled list\n    }","handlingStrategy":"retry","validationCode":"// Pre-check connectivity and the resolved URL before requesting the codes.\nif (string.IsNullOrEmpty(path) || !Uri.IsWellFormedUriString(path, UriKind.Absolute))\n    throw new InvalidOperationException(\"Language codes path is not a valid URL.\");\n\nif (!NetworkHelper.IsOnline())\n    throw new WebException(\"No network connectivity to fetch language codes.\");","typeGuard":"static bool HasReadableBody(HttpWebResponse response) =>\n    response != null && (int)response.StatusCode < 400 && response.ContentLength != 0;\n\nvar response = (HttpWebResponse)await request.GetResponseAsync();\nif (!HasReadableBody(response))\n    return Enumerable.Empty<string>(); // let caller use bundled fallback","tryCatchPattern":"// Retry once on a null/empty stream, then degrade to the bundled list.\nIEnumerable<string> result = null;\nfor (var attempt = 0; attempt < 2 && result == null; attempt++)\n{\n    try { result = await GetLanguageCodesAsync(); }\n    catch (WebException wex) when (wex.Message.Contains(\"Empty response from server when getting language codes\"))\n    {\n        LogWriter.Log(wex, $\"Null language-codes stream on attempt {attempt + 1}.\");\n        if (attempt == 1) return GetBundledLanguageCodes();\n        await Task.Delay(500);\n    }\n}\nreturn result;","preventionTips":["Check response.StatusCode and ContentLength before relying on GetResponseStream().","Retry transient null-stream responses once before failing.","Verify WebHelper.GetProxy() isn't stripping response bodies.","Always have a bundled/offline language-code fallback so network edges don't break localization."],"tags":["network","webexception","http","stream","localization","proxy"],"backgroundTag":null,"analyzedSha":"a4d0a67c2131cd048ceec86cd40afc2f1a06f2fd","analyzedAt":"2026-08-13T11:12:06.147Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}