{"record":{"id":"c9e52c765ca489d7","repo":"siyuan-note/siyuan","slug":"request-failed-s","errorCode":null,"errorMessage":"request failed: %s","messagePattern":"request failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/util/httprequest.go","lineNumber":88,"sourceCode":"\t\treturn 0, \"\", \"\", serr\n\t}\n\n\tmethod = strings.ToUpper(strings.TrimSpace(method))\n\tif method == \"\" {\n\t\tmethod = \"GET\"\n\t}\n\n\trequest := httpclient.NewBrowserRequest()\n\tfor k, v := range headers {\n\t\trequest.SetHeader(k, v)\n\t}\n\tif body != \"\" && method != \"GET\" && method != \"HEAD\" {\n\t\trequest.SetBody(body)\n\t}\n\n\tresp, err := sendByMethod(request, method, rawURL)\n\tif err != nil {\n\t\treturn 0, \"\", \"\", errors.New(\"request failed: \" + err.Error())\n\t}\n\tif resp == nil {\n\t\treturn 0, \"\", \"\", errors.New(\"nil response\")\n\t}\n\tdefer resp.Body.Close()\n\n\tstatusCode = resp.StatusCode\n\tcontentType = resp.Header.Get(\"Content-Type\")\n\n\tmaxReadBytes := int64(maxHTTPRequestBytes)\n\tif !isTextContentType(contentType) {\n\t\tmaxReadBytes = maxHTTPRequestFileBytes\n\t}\n\t// ContentLength 为 -1（chunked）时跳过大小预检，交由 LimitReader 兜底截断。\n\tif resp.ContentLength > maxReadBytes {\n\t\treturn statusCode, contentType, \"\", errors.New(\"response too large\")\n\t}\n","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/util/httprequest.go#L70-L106","documentation":"Returned by HTTPRequest when sendByMethod returns a non-nil error — i.e. the underlying req/v3 HTTP client failed to send or receive (DNS done by SSRF precheck already passed; this is transport-level). The original error text is appended for diagnostics. A nil response is handled separately (errorIndex 'nil response' neighbour).","triggerScenarios":"After passing URL/scheme/host/SSRF checks, the actual httpclient.NewBrowserRequest().Get/Post/... call fails: connection refused, TLS handshake error, dial timeout, broken connection mid-request, or proxy failure.","commonSituations":"The server is down or refusing connections; a TLS certificate is invalid or expired; a corporate proxy is unreachable; the network dropped mid-request; a firewall reset the connection.","solutions":["Inspect the appended transport error — 'connection refused' means the port is closed, 'TLS' means a certificate issue, 'i/o timeout' means reachability.","Retry once for transient transport failures (reset, timeout); do not retry for TLS errors.","If a proxy is required, confirm httpclient is configured with the proxy env (HTTP_PROXY/HTTPS_PROXY)."],"exampleFix":"// before\n_, _, _, err := util.HTTPRequest(\"GET\", rawURL, nil, \"\")\n\n// after\nvar lastErr error\nfor attempt := 0; attempt < 2; attempt++ {\n    _, _, _, lastErr = util.HTTPRequest(\"GET\", rawURL, nil, \"\")\n    if lastErr == nil || isTLSNetError(lastErr) {\n        break\n    }\n    time.Sleep(500 * time.Millisecond)\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"var err error\nfor attempt := 0; attempt < 2; attempt++ {\n    _, _, _, err = util.HTTPRequest(method, rawURL, headers, body)\n    if err == nil || !isTransientTransport(err) { break }\n    time.Sleep(500 * time.Millisecond)\n}","preventionTips":["Distinguish TLS errors (do not retry) from reset/timeout (retry once).","Confirm proxy configuration (HTTP_PROXY/HTTPS_PROXY) when connectivity is fine but requests fail."],"tags":["network","http","transport","http-request"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}