{"record":{"id":"8426c9072c0810fb","repo":"fish2018/pansou","slug":"detail-request-failed-w","errorCode":null,"errorMessage":"detail request failed: %w","messagePattern":"detail request failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/discourse/discourse.go","lineNumber":477,"sourceCode":"\t}\n\t\n\treturn content\n}\n\n// GetTopicDetail 获取主题详情（可选实现，用于获取完整链接）\nfunc (p *DiscourseAsyncPlugin) GetTopicDetail(topicID int) ([]model.Link, error) {\n\t// 检查 cloudscraper 是否初始化成功\n\tif p.scraper == nil {\n\t\treturn nil, fmt.Errorf(\"cloudscraper not initialized\")\n\t}\n\n\t// 构建详情URL\n\tdetailURL := fmt.Sprintf(detailURLTemplate, topicID)\n\n\t// 发送详情请求\n\tresp, err := p.scraper.Get(detailURL)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"detail request failed: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\t// 检查HTTP状态码\n\tif resp.StatusCode != 200 {\n\t\treturn nil, fmt.Errorf(\"unexpected status code: %d\", resp.StatusCode)\n\t}\n\n\t// 读取响应体\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"read response failed: %w\", err)\n\t}\n\n\t// 解析JSON响应\n\tvar detailResp DetailResponse\n\tif err := json.Unmarshal(body, &detailResp); err != nil {\n\t\treturn nil, fmt.Errorf(\"parse json failed: %w\", err)","sourceCodeStart":459,"sourceCodeEnd":495,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/discourse/discourse.go#L459-L495","documentation":"Wrapped network error in DiscourseAsyncPlugin.GetTopicDetail (plugin/discourse/discourse.go:477): the cloudscraper GET to the topic detail URL failed before any response was produced (DNS, TLS, timeout, or anti-bot challenge failure). No HTTP status exists at this point, so upstream code cannot retry with status-based logic from this error alone.","triggerScenarios":"p.scraper.Get(detailURL) returns a non-nil error — DNS failure, connection refused/reset, timeout, TLS error, or cloudflare bypass failure.","commonSituations":"目标站点不可达、本地网络断开、代理配置错误。","solutions":["Check the wrapped error to identify DNS/connect/TLS cause","Verify the site URL is correct and reachable in a browser","Confirm cloudscraper solved the Cloudflare challenge (403/503 with cf pages)","Check proxy/VPN and firewall settings","Retry on transient network errors with backoff"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"u, err := url.Parse(detailURL)\nif err != nil || u.Scheme == \"\" || u.Host == \"\" {\n    return fmt.Errorf(\"invalid detail url: %q\", detailURL)\n}","typeGuard":null,"tryCatchPattern":"links, err := plugin.GetTopicDetail(id)\nif err != nil && strings.Contains(err.Error(), \"detail request failed\") {\n    var nerr net.Error\n    if errors.As(errors.Unwrap(err), &nerr) && nerr.Timeout() {\n        time.Sleep(backoff)\n        links, err = plugin.GetTopicDetail(id)\n    }\n}","preventionTips":["Verify site reachability before batch fetching","Use sane timeouts and retry with backoff for transient failures","Keep proxy configuration correct"],"tags":["network","http","cloudflare","discourse"],"backgroundTag":"http-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"}