{"record":{"id":"eb4db0a309ecc6b8","repo":"Tencent/WeKnora","slug":"download-jsonl-w","errorCode":null,"errorMessage":"download jsonl: %w","messagePattern":"download jsonl: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/infrastructure/docparser/paddleocr_vl_cloud_converter.go","lineNumber":271,"sourceCode":"type paddleOCRVLCloudResultLine struct {\n\tResult struct {\n\t\tLayoutParsingResults []struct {\n\t\t\tMarkdown struct {\n\t\t\t\tText   string            `json:\"text\"`\n\t\t\t\tImages map[string]string `json:\"images\"`\n\t\t\t} `json:\"markdown\"`\n\t\t} `json:\"layoutParsingResults\"`\n\t} `json:\"result\"`\n}\n\nfunc (c *PaddleOCRVLCloudReader) fetchResults(jsonlURL string) (string, map[string]string, error) {\n\tif err := utils.ValidateURLForSSRF(jsonlURL); err != nil {\n\t\treturn \"\", nil, fmt.Errorf(\"jsonl URL blocked by SSRF check: %v\", err)\n\t}\n\tclient := utils.NewSSRFSafeHTTPClient(utils.SSRFSafeHTTPClientConfig{Timeout: 120 * time.Second, MaxRedirects: 5})\n\tresp, err := client.Get(jsonlURL)\n\tif err != nil {\n\t\treturn \"\", nil, fmt.Errorf(\"download jsonl: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn \"\", nil, fmt.Errorf(\"download jsonl status %d\", resp.StatusCode)\n\t}\n\tdata, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn \"\", nil, fmt.Errorf(\"read jsonl body: %w\", err)\n\t}\n\n\ttexts := make([]string, 0)\n\timages := make(map[string]string)\n\tfor _, line := range strings.Split(strings.TrimSpace(string(data)), \"\\n\") {\n\t\tline = strings.TrimSpace(line)\n\t\tif line == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tvar parsed paddleOCRVLCloudResultLine","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/infrastructure/docparser/paddleocr_vl_cloud_converter.go#L253-L289","documentation":"fetchResults downloads the JSONL result file from the provider using an SSRF-safe HTTP client; this error wraps any transport-level failure of that GET (DNS failure, connection refused/reset, TLS error, timeout after the 120s client timeout, or redirect issues). It is returned to Read, failing the parse even though the remote task itself succeeded.","triggerScenarios":"client.Get(jsonlURL) inside fetchResults returns a non-nil error after the task already completed and passed the SSRF check — network outage, DNS resolution failure, TLS handshake failure, or the 120-second client timeout elapsing on a very large result.","commonSituations":"Egress firewall/proxy blocking the result-hosting domain; DNS misconfiguration in containers/Kubernetes; very large JSONL results exceeding the 120s timeout on slow links; provider CDN returning connection resets; expired TLS certificates on the result host.","solutions":["Retry Read (or just the download) — transient network/CDN failures usually clear.","Increase the SSRF-safe client Timeout above 120s if the JSONL result is very large or the link is slow.","Verify egress connectivity: DNS resolution, proxy env vars (HTTP(S)_PROXY), and firewall rules for the result host.","Check TLS validity of the result host (expired/mismatched certificate) with curl/openssl.","If timeouts recur, stream the body to disk instead of io.ReadAll within one blocking request, or fetch via a resumable/ranged download."],"exampleFix":"// before\nclient := utils.NewSSRFSafeHTTPClient(utils.SSRFSafeHTTPClientConfig{Timeout: 120 * time.Second, MaxRedirects: 5})\n\n// after: larger timeout plus caller-side retry\nvar data []byte\nbackoff := 2 * time.Second\nfor attempt := 0; attempt < 3; attempt++ {\n    data, err = downloadJSONL(jsonlURL, 300*time.Second)\n    if err == nil { break }\n    time.Sleep(backoff)\n    backoff *= 2\n}","handlingStrategy":"retry","validationCode":"// verify the result host is reachable and cert-valid before the full download\nif err := utils.ValidateURLForSSRF(jsonlURL); err != nil {\n    return err\n}\nconn, err := net.DialTimeout(\"tcp\", hostOf(jsonlURL)+\":443\", 5*time.Second)\nif err != nil { return fmt.Errorf(\"result host unreachable: %w\", err) }\nconn.Close()","typeGuard":null,"tryCatchPattern":"data, err := downloadWithRetry(jsonlURL, 3, time.Second)\nif err != nil && strings.Contains(err.Error(), \"download jsonl\") {\n    // check network, DNS, proxy and TLS before surfacing to the user\n    return fmt.Errorf(\"could not fetch OCR result (network?): %w\", err)\n}","preventionTips":["Configure retries with exponential backoff for result downloads.","Raise the HTTP client timeout for large JSONL results or slow links.","Verify egress DNS, proxy (HTTP(S)_PROXY), and firewall rules in the deployment environment.","Monitor certificate expiry of the provider result host."],"tags":["network","http","download","ocr"],"backgroundTag":"http-request-failed","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}