SubtitleEdit/subtitleedit · error · OcrException

Error calling Cloud Vision API

Error message

Error calling Cloud Vision API: {httpException.Message}

What it means

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.

Solutions

  1. Confirm network connectivity and that vision.googleapis.com resolves.
  2. Configure the HttpClient with the required proxy (HttpClientHandler.Proxy / WebProxy).
  3. Update the system certificate store / .NET root certificates for TLS.
  4. Retry transient network blips; if persistent, fall back to a local OCR engine (tesseract/nocr).

Example fix

// configure proxy on the HttpClient handed to GoogleVisionOcr
var handler = new HttpClientHandler { UseProxy = true, Proxy = new WebProxy("http://proxy:8080") };
var http = new HttpClient(handler) { BaseAddress = new Uri("https://vision.googleapis.com/v1/images:annotate") };
Defensive patterns

Strategy: retry

Validate before calling

// Pre-flight connectivity check
try { await _httpClient.GetAsync("/", ct); } catch (HttpRequestException ex) { throw new OcrException("Cannot reach Vision API: " + ex.Message, ex); }

Type guard

null

Try / catch

try { return await ocr.Ocr(bmp, key, lang, ct); }
catch (OcrException ex) when (ex.InnerException is HttpRequestException) {
    // network/proxy/TLS — retry once or fall back to a local OCR engine
    return await FallbackLocalOcr(bmp); }

Prevention

When it happens

Trigger: _httpClient.PostAsync throws HttpRequestException (no response obtained): offline, no network, DNS for the Vision host fails, proxy blocks the call, or TLS handshake fails.

Common situations: Running OCR offline or behind a corporate proxy that blocks vision.googleapis.com; DNS misconfiguration; expired/missing root certificates; HttpClient disposed mid-call.

Related errors


AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13). Data as JSON: /api/errors/20de4fd195e38c40. Report an issue: GitHub.

Appendix: source

Thrown at src/ui/Features/Ocr/Engines/GoogleVisionOcr.cs:207

            {
                throw new OcrException("API key invalid (or perhaps billing/API is not enabled)?");
            }

            if ((int)result.StatusCode == 403)
            {
                throw new OcrException("\"Perhaps billing is not enabled (or API not enabled or API key is invalid)?\"");
            }

            if (!result.IsSuccessStatusCode)
            {
                throw new OcrException($"An error occurred calling Cloud Vision API - status code: {result.StatusCode}");
            }

            content = await result.Content.ReadAsStringAsync(cancellationToken);
        }
        catch (HttpRequestException httpException)
        {
            throw new OcrException("Error calling Cloud Vision API: " + httpException.Message, httpException);
        }

        return string.Join(Environment.NewLine, JsonToStringList(language, content));
    }

    public static List<string> JsonToStringList(string language, string content)
    {
        if (Configuration.Settings.Tools.OcrGoogleCloudVisionSeHandlesTextMerge)
        {
            var annotations = GetAnnotations(content).ToList();
            if (annotations.Count > 0)
            {
                var lines = new List<List<Annotation>>();
                Annotation? last = null;
                var lineThreshold = Math.Max(9, annotations.Average(p => p.Height) / 4.0);
                var lineIndex = 0;

                // Split to lines

View on GitHub (pinned to 17a9f07487)