{"record":{"id":"f88ccab7b2fee141","repo":"fish2018/pansou","slug":"w-f88cca","errorCode":null,"errorMessage":"读取响应失败: %w","messagePattern":"读取响应失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/panyq/panyq.go","lineNumber":679,"sourceCode":"\t\treturn nil, fmt.Errorf(\"请求网站首页失败: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\t\n\t// 检查状态码\n\tif resp.StatusCode != http.StatusOK {\n\t\t// 读取响应体以获取服务器返回的具体错误信息\n\t\tbodyBytes, err := io.ReadAll(resp.Body)\n\t\tif err != nil {\n\t\t\t// 如果连响应体都读取失败，则返回状态码错误并附上读取错误\n\t\t\treturn nil, fmt.Errorf(\"请求失败，状态码: %d，且读取响应体错误: %v\", resp.StatusCode, err)\n\t\t}\n\t\t// 将更详细的状态信息 (如 \"404 Not Found\") 和响应体内容一起作为错误返回\n\t\treturn nil, fmt.Errorf(\"请求失败，状态: %s, 详情: %s\", resp.Status, string(bodyBytes))\n\t}\n\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"读取响应失败: %w\", err)\n\t}\n\t\n\t// 提取JS文件路径\n\tjsRegex := regexp.MustCompile(`<script src=\"(/_next/static/[^\"]+\\.js)\"`)\n\tmatches := jsRegex.FindAllStringSubmatch(string(body), -1)\n\t\n\tif len(matches) == 0 {\n\t\treturn nil, fmt.Errorf(\"未找到JS文件\")\n\t}\n\t\n\t// 收集所有潜在的Action ID\n\tidSet := make(map[string]struct{})\n\tidRegex := regexp.MustCompile(`[\"\\']([a-f0-9]{40})[\"\\']{1}`)\n\t\n\tfor _, match := range matches {\n\t\tjsURL := BaseURL + match[1]\n\t\t\n\t\t// 创建JS文件请求","sourceCodeStart":661,"sourceCodeEnd":697,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/panyq/panyq.go#L661-L697","documentation":"The homepage returned 200 OK, but reading the full response body with io.ReadAll failed. The body is required to extract Next.js script paths, so the function cannot proceed. Causes are transport-level: connection reset while streaming the body, context deadline exceeded, or decompression errors (e.g. unexpected gzip/brotli content).","triggerScenarios":"resp.StatusCode == 200 but io.ReadAll(resp.Body) in findPotentialActionIDs errors — server drops the connection mid-body, request context times out, or the client cannot decode the content-encoding (brotli responses when only gzip is supported).","commonSituations":"Large homepage over a flaky connection; missing Accept-Encoding header causing server to send an encoding the client can't decode; proxy terminating long responses; mobile/unstable networks.","solutions":["Use io.ReadAll with a bounded reader and retry the whole request on failure; body-read resets are usually transient.","Ensure the request sets an Accept-Encoding header matching what the client Transport can decompress (prefer letting net/http handle it by not setting Accept-Encoding manually).","Increase the client Timeout / use a context with a longer deadline.","Check proxy stability if requests go through an intermediary.","Log the bytes read so far (if any) to see whether the body was truncated or entirely empty."],"exampleFix":"// before\nbody, err := io.ReadAll(resp.Body)\nif err != nil {\n    return nil, fmt.Errorf(\"读取响应失败: %w\", err)\n}\n// after\nbody, err := io.ReadAll(io.LimitReader(resp.Body, 10<<20))\nif err != nil {\n    return nil, fmt.Errorf(\"读取响应失败: %w\", err)\n}\nif len(body) == 0 {\n    return nil, fmt.Errorf(\"读取响应失败: 响应体为空\")\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"body, err := io.ReadAll(resp.Body)\nif err != nil {\n    if isTransientIO(err) {\n        return retryFetch(req, 3)\n    }\n    return nil, fmt.Errorf(\"读取响应失败: %w\", err)\n}","preventionTips":["Let net/http negotiate compression instead of setting Accept-Encoding manually unless you support the encodings.","Use io.LimitReader to bound body size and avoid pathological reads.","Increase client timeout for large pages or slow networks.","Retry whole requests on mid-body connection resets."],"tags":["network","http","io","go"],"backgroundTag":"network-request-failed","analyzedSha":"beaa56133755a548ebc51b090b3816e2ae044aa6","analyzedAt":"2026-09-07T00:31:18.025Z","contentChangedAt":"2026-09-07T00:31:18.025Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}