{"record":{"id":"20de4fd195e38c40","repo":"SubtitleEdit/subtitleedit","slug":"error-calling-cloud-vision-api-httpexception-mes","errorCode":null,"errorMessage":"Error calling Cloud Vision API: {httpException.Message}","messagePattern":"Error calling Cloud Vision API: (.+?)","errorType":"exception","errorClass":"OcrException","httpStatus":null,"severity":"error","filePath":"src/ui/Features/Ocr/Engines/GoogleVisionOcr.cs","lineNumber":207,"sourceCode":"            {\n                throw new OcrException(\"API key invalid (or perhaps billing/API is not enabled)?\");\n            }\n\n            if ((int)result.StatusCode == 403)\n            {\n                throw new OcrException(\"\\\"Perhaps billing is not enabled (or API not enabled or API key is invalid)?\\\"\");\n            }\n\n            if (!result.IsSuccessStatusCode)\n            {\n                throw new OcrException($\"An error occurred calling Cloud Vision API - status code: {result.StatusCode}\");\n            }\n\n            content = await result.Content.ReadAsStringAsync(cancellationToken);\n        }\n        catch (HttpRequestException httpException)\n        {\n            throw new OcrException(\"Error calling Cloud Vision API: \" + httpException.Message, httpException);\n        }\n\n        return string.Join(Environment.NewLine, JsonToStringList(language, content));\n    }\n\n    public static List<string> JsonToStringList(string language, string content)\n    {\n        if (Configuration.Settings.Tools.OcrGoogleCloudVisionSeHandlesTextMerge)\n        {\n            var annotations = GetAnnotations(content).ToList();\n            if (annotations.Count > 0)\n            {\n                var lines = new List<List<Annotation>>();\n                Annotation? last = null;\n                var lineThreshold = Math.Max(9, annotations.Average(p => p.Height) / 4.0);\n                var lineIndex = 0;\n\n                // Split to lines","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/SubtitleEdit/subtitleedit/blob/17a9f0748781032255db3526b7215d2fb891e3af/src/ui/Features/Ocr/Engines/GoogleVisionOcr.cs#L189-L225","documentation":"Thrown by GoogleVisionOcr.Ocr when PostAsync raises HttpRequestException — i.e. the call never reached a HTTP response. This covers DNS failure, connection refused, TLS errors, socket exhaustion, and timeouts at the transport layer. The original HttpRequestException is preserved as InnerException.","triggerScenarios":"_httpClient.PostAsync throws HttpRequestException (no response obtained): offline, no network, DNS for the Vision host fails, proxy blocks the call, or TLS handshake fails.","commonSituations":"Running OCR offline or behind a corporate proxy that blocks vision.googleapis.com; DNS misconfiguration; expired/missing root certificates; HttpClient disposed mid-call.","solutions":["Confirm network connectivity and that vision.googleapis.com resolves.","Configure the HttpClient with the required proxy (HttpClientHandler.Proxy / WebProxy).","Update the system certificate store / .NET root certificates for TLS.","Retry transient network blips; if persistent, fall back to a local OCR engine (tesseract/nocr)."],"exampleFix":"// configure proxy on the HttpClient handed to GoogleVisionOcr\nvar handler = new HttpClientHandler { UseProxy = true, Proxy = new WebProxy(\"http://proxy:8080\") };\nvar http = new HttpClient(handler) { BaseAddress = new Uri(\"https://vision.googleapis.com/v1/images:annotate\") };","handlingStrategy":"retry","validationCode":"// Pre-flight connectivity check\ntry { await _httpClient.GetAsync(\"/\", ct); } catch (HttpRequestException ex) { throw new OcrException(\"Cannot reach Vision API: \" + ex.Message, ex); }","typeGuard":"null","tryCatchPattern":"try { return await ocr.Ocr(bmp, key, lang, ct); }\ncatch (OcrException ex) when (ex.InnerException is HttpRequestException) {\n    // network/proxy/TLS — retry once or fall back to a local OCR engine\n    return await FallbackLocalOcr(bmp); }","preventionTips":["Configure the HttpClient with the correct proxy and base address once.","Keep the system trust store / .NET roots current for TLS.","Have a local OCR fallback (tesseract/nocr) for offline runs."],"tags":["subtitle-edit","ocr","google-vision","http-request-exception","network","proxy","tls"],"backgroundTag":null,"analyzedSha":"17a9f0748781032255db3526b7215d2fb891e3af","analyzedAt":"2026-08-13T18:11:43.374Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}