{"record":{"id":"17eebaef9da3d0fe","repo":"fish2018/pansou","slug":"w-17eeba","errorCode":null,"errorMessage":"读取响应体失败: %w","messagePattern":"读取响应体失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/xb6v/xb6v.go","lineNumber":205,"sourceCode":"\t\tlog.Printf(\"[Xb6v] POST响应状态码: %d\", resp.StatusCode)\n\t}\n\n\t// 获取重定向的location\n\tlocation := resp.Header.Get(\"Location\")\n\tif p.debugMode {\n\t\tlog.Printf(\"[Xb6v] Location头: '%s'\", location)\n\t}\n\n\t// 如果没有Location头，可能需要从响应体中解析\n\tif location == \"\" {\n\t\tif p.debugMode {\n\t\t\tlog.Printf(\"[Xb6v] 未找到Location头，尝试解析响应体\")\n\t\t}\n\n\t\t// 读取响应体看看是否包含重定向信息\n\t\tbodyReader, err := p.getResponseReader(resp)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"读取响应体失败: %w\", err)\n\t\t}\n\n\t\tbodyBytes, err := io.ReadAll(bodyReader)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"读取响应体失败: %w\", err)\n\t\t}\n\n\t\tbodyStr := string(bodyBytes)\n\t\tif p.debugMode {\n\t\t\tlog.Printf(\"[Xb6v] 响应体长度: %d\", len(bodyStr))\n\t\t\t// 只打印前500个字符避免日志过长\n\t\t\tif len(bodyStr) > 500 {\n\t\t\t\tlog.Printf(\"[Xb6v] 响应体前500字符: %s\", bodyStr[:500])\n\t\t\t} else {\n\t\t\t\tlog.Printf(\"[Xb6v] 响应体内容: %s\", bodyStr)\n\t\t\t}\n\t\t}\n","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/xb6v/xb6v.go#L187-L223","documentation":"When the xb6v search POST returns no Location header, searchImpl falls back to parsing the response body for a redirect. It obtains a reader via p.getResponseReader(resp) (which likely handles gzip/charset) and wraps any failure of that reader setup — or of the subsequent io.ReadAll — as this error. It means the redirect-bearing body could not be obtained or decoded.","triggerScenarios":"Either p.getResponseReader(resp) errors (unhandled Content-Encoding/charset, e.g. an unexpected gzip/brotli payload) or io.ReadAll(bodyReader) fails (connection reset mid-body, timeout during transfer, corrupt chunked encoding). Only reached when the search POST returned 200/3xx without a Location header.","commonSituations":"The site starts serving brotli (br) or zstd encoding the reader does not support; the server truncates the response mid-transfer; the response is HTML stating an error but encoded unusually; flaky network to the target.","solutions":["Log resp.Header.Get(\"Content-Encoding\") when this fires; extend getResponseReader to handle the encoding (e.g. brotli) or send 'Accept-Encoding: gzip' explicitly so the server uses a supported one.","Unwrap the error to distinguish reader-setup failure (encoding) from io.ReadAll failure (transport); retry the request for the latter.","Check the response Content-Type/charset and ensure the reader decodes non-UTF8 charsets correctly.","Increase the request timeout if large bodies are cut off mid-read.","Prefer forcing a supported encoding on the request so the fallback body parse is reliable."],"exampleFix":"// before\nbodyReader, err := p.getResponseReader(resp)\nif err != nil {\n    return nil, fmt.Errorf(\"读取响应体失败: %w\", err)\n}\n// after\nbodyReader, err := p.getResponseReader(resp)\nif err != nil {\n    return nil, fmt.Errorf(\"读取响应体失败 (Content-Encoding=%q): %w\", resp.Header.Get(\"Content-Encoding\"), err)\n}","handlingStrategy":"try-catch","validationCode":"enc := resp.Header.Get(\"Content-Encoding\")\nif enc != \"\" && enc != \"gzip\" && enc != \"deflate\" && enc != \"identity\" {\n    return fmt.Errorf(\"unsupported Content-Encoding: %s\", enc)\n}","typeGuard":null,"tryCatchPattern":"bodyReader, err := p.getResponseReader(resp)\nif err != nil {\n    return nil, fmt.Errorf(\"读取响应体失败 (encoding=%q): %w\", resp.Header.Get(\"Content-Encoding\"), err)\n}","preventionTips":["Send an explicit supported Accept-Encoding header on requests","Extend the response reader for new encodings (br, zstd) before the site adopts them","Retry transport-level read errors; treat encoding errors as code fixes","Verify charset handling for non-UTF8 responses"],"tags":["http","io","encoding","scraping"],"backgroundTag":"file-read-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"}