{"record":{"id":"7db58f541b89701a","repo":"fish2018/pansou","slug":"s-w-7db58f","errorCode":null,"errorMessage":"[%s] 读取搜索结果失败: %w","messagePattern":"\\[(.+?)\\] 读取搜索结果失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/dygang/dygang.go","lineNumber":189,"sourceCode":"\tctx, cancel := context.WithTimeout(context.Background(), requestTimeout)\n\tdefer cancel()\n\treq, err := http.NewRequestWithContext(ctx, http.MethodPost, baseURL+searchPath, strings.NewReader(form))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 创建搜索请求失败: %w\", p.Name(), err)\n\t}\n\tsetHeaders(req, baseURL+\"/\")\n\treq.Header.Set(\"Content-Type\", \"application/x-www-form-urlencoded\")\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 搜索请求失败: %w\", p.Name(), err)\n\t}\n\tdefer resp.Body.Close()\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"[%s] 搜索请求返回 HTTP %d\", p.Name(), resp.StatusCode)\n\t}\n\tbody, err := io.ReadAll(io.LimitReader(resp.Body, 4<<20))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 读取搜索结果失败: %w\", p.Name(), err)\n\t}\n\tdecoded, err := decodeGB18030(body)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 解码搜索结果失败: %w\", p.Name(), err)\n\t}\n\tdoc, err := goquery.NewDocumentFromReader(strings.NewReader(decoded))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 解析搜索结果失败: %w\", p.Name(), err)\n\t}\n\treturn doc, nil\n}\n\nfunc (p *Plugin) fetchDetail(client *http.Client, detailURL string) ([]magnetItem, string, string) {\n\tctx, cancel := context.WithTimeout(context.Background(), requestTimeout)\n\tdefer cancel()\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, detailURL, nil)\n\tif err != nil {\n\t\treturn nil, \"\", \"\"","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/dygang/dygang.go#L171-L207","documentation":"Reading the response body via io.ReadAll(io.LimitReader(resp.Body, 4<<20)) failed, so the search results could not be loaded. This wraps the underlying read error (usually a network interruption or server closing the connection mid-body, surfaced as unexpected EOF or connection reset). The body is capped at 4 MiB to bound memory use.","triggerScenarios":"io.ReadAll returns an error while draining resp.Body: connection reset by peer, unexpected EOF, or any transport error occurring after headers were received but before the full body arrived.","commonSituations":"Flaky upstream connection, server timing out and dropping the connection mid-response, intermediate proxies killing long transfers, or mobile/unstable networks.","solutions":["Retry the search request — this is typically transient.","Unwrap the error to distinguish io.ErrUnexpectedEOF / connection reset from other failures.","If it recurs on large pages, check whether a proxy or timeout is cutting the transfer short.","Consider reusing a shared http.Client with sane Transport timeouts and connection pooling."],"exampleFix":"// before\nbody, err := io.ReadAll(io.LimitReader(resp.Body, 4<<20))\nif err != nil {\n\treturn nil, fmt.Errorf(\"[%s] 读取搜索结果失败: %w\", p.Name(), err)\n}\n// after\nbody, err := io.ReadAll(io.LimitReader(resp.Body, 4<<20))\nif err != nil {\n\treturn nil, fmt.Errorf(\"[%s] 读取搜索结果失败(可重试): %w\", p.Name(), err)\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err != nil {\n\tif errors.Is(err, io.ErrUnexpectedEOF) || errors.Is(err, syscall.ECONNRESET) { /* transient: retry */ }\n\treturn nil, fmt.Errorf(\"[%s] 读取搜索结果失败: %w\", p.Name(), err)\n}","preventionTips":["Retry body-read failures — they are usually transient connection drops","Configure the http.Client Transport with sane timeouts and keep-alives","Keep the LimitReader cap so partial reads never exhaust memory"],"tags":["http","io","network","response-body"],"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"}