{"record":{"id":"b8201fa86b74bf57","repo":"fish2018/pansou","slug":"d-w-b8201f","errorCode":null,"errorMessage":"重试 %d 次后失败: %w","messagePattern":"重试 (.+?) 次后失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/daishudj/daishudj.go","lineNumber":436,"sourceCode":"}\n\nfunc (p *DaishuPlugin) doRequestWithRetry(req *http.Request, client *http.Client) (*http.Response, error) {\n\tvar lastErr error\n\tfor attempt := 0; attempt < maxRetries; attempt++ {\n\t\tresp, err := client.Do(req.Clone(req.Context()))\n\t\tif err == nil && resp.StatusCode == http.StatusOK {\n\t\t\treturn resp, nil\n\t\t}\n\t\tif resp != nil {\n\t\t\tresp.Body.Close()\n\t\t}\n\t\tlastErr = err\n\t\tif attempt < maxRetries-1 {\n\t\t\tbackoff := retryBaseDelay * time.Duration(1<<attempt)\n\t\t\ttime.Sleep(backoff)\n\t\t}\n\t}\n\treturn nil, fmt.Errorf(\"重试 %d 次后失败: %w\", maxRetries, lastErr)\n}\n\nfunc startCacheCleaner() {\n\tticker := time.NewTicker(cacheCleanupInterval)\n\tdefer ticker.Stop()\n\n\tfor range ticker.C {\n\t\tnow := time.Now()\n\t\tdetailCache.Range(func(key, value interface{}) bool {\n\t\t\tentry, ok := value.(cacheEntry)\n\t\t\tif !ok || now.After(entry.expiresAt) {\n\t\t\t\tdetailCache.Delete(key)\n\t\t\t}\n\t\t\treturn true\n\t\t})\n\t}\n}\n","sourceCodeStart":418,"sourceCodeEnd":454,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/daishudj/daishudj.go#L418-L454","documentation":"doRequestWithRetry performs HTTP requests with exponential backoff (retryBaseDelay * 2^attempt) for up to maxRetries attempts. If every attempt fails, it returns this error wrapping the last underlying error with %w. It aggregates persistent transport failures after exhausting the retry budget.","triggerScenarios":"Any call chain through searchImpl or fetchDetailLinks that reaches doRequestWithRetry while the target host is unreachable, times out, resets connections, or returns repeatedly failing responses on all maxRetries attempts.","commonSituations":"Site is down or blocking the client; DNS failure in the deployment environment; timeout too aggressive for a slow upstream; corporate proxy/firewall blocking outbound requests; retryBaseDelay/backoff insufficient during rate limiting.","solutions":["Inspect the wrapped lastErr (errors.Unwrap / %w chain) to find the true root cause (timeout, connection refused, TLS).","Confirm network egress and DNS resolution from the host running the plugin.","Increase maxRetries or retryBaseDelay if the upstream is intermittently slow or rate limiting.","Retry later if the target site is temporarily down; consider a proxy or alternate mirror."],"exampleFix":"// before\nres, err := p.doRequestWithRetry(client, url)\nif err != nil { return err }\n// after\nres, err := p.doRequestWithRetry(client, url)\nif err != nil {\n    var netErr net.Error\n    if errors.As(err, &netErr) && netErr.Timeout() {\n        return fmt.Errorf(\"upstream timeout, try increasing client timeout: %w\", err)\n    }\n    return err\n}","handlingStrategy":"retry","validationCode":"// pre-flight reachability check\nif _, err := net.LookupTimeout(ctx, \"tcp\", host+\":443\", 5*time.Second); err != nil {\n    return fmt.Errorf(\"host unreachable before request: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err != nil {\n    var netErr net.Error\n    if errors.As(err, &netErr) && netErr.Timeout() {\n        // schedule retry with longer backoff\n    }\n    return fmt.Errorf(\"all retries exhausted: %w\", err)\n}","preventionTips":["Tune maxRetries and retryBaseDelay to the upstream's failure profile.","Monitor site availability before running bulk scrape jobs.","Always inspect the wrapped root error, not just the wrapper message.","Use proxies/circuit breakers for flaky upstreams."],"tags":["network","retry","http","plugin","go"],"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"}