fish2018/pansou · error

[ ] 请求失败,重试 次后仍失败

Error message

[%s] 请求失败,重试%d次后仍失败: %w

What it means

Final failure of doRequestWithRetry: after maxRetries attempts (with 100ms sleeps between them) the request never succeeded, so the last error is wrapped with the plugin name and the retry count via %w. Callers receive this from searchImpl as the cause of error 470.

Solutions

  1. Look at the wrapped cause (errors.Unwrap) to distinguish network failure from status failure
  2. Wait and retry later with a longer backoff than the built-in 100ms
  3. Test reachability of https://woog.nxog.eu.org/ independently (curl, DNS lookup)
  4. If rate limiting, reduce request frequency or add jitter/proxy rotation before retrying

Example fix

// before
if err != nil { return err }
// after
var retried *RetryExhaustedError
if errors.As(err, &retried) {
    time.Sleep(2 * time.Second)
    return secondAttempt()
}
Defensive patterns

Strategy: fallback

Validate before calling

func hostUp(host string) bool {
    c, err := net.DialTimeout("tcp", host+":443", 3*time.Second)
    if err != nil { return false }
    c.Close()
    return true
}

Try / catch

if err != nil {
    if strings.Contains(err.Error(), "重试") { // retries exhausted
        return alternatePluginSearch(keyword) // fallback source
    }
    return err
}

Prevention

When it happens

Trigger: All attempts in the retry loop fail — persistent network errors, timeouts, or repeated non-200 statuses (error 474) — then the loop exits and this error is returned.

Common situations: The API host is fully down or DNS-blackholed; aggressive rate limiting survives the 100ms backoff; firewall blocks outbound HTTPS; the 100ms fast-retry policy is too short for a temporarily degraded upstream.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07). Data as JSON: /api/errors/fce74bdc09c150dc. Report an issue: GitHub.

Appendix: source

Thrown at plugin/ouge/ouge.go:423

	for i := 0; i < maxRetries; i++ {
		resp, err := client.Do(req)
		if err == nil {
			if resp.StatusCode == http.StatusOK {
				return resp, nil
			}
			resp.Body.Close()
			lastErr = fmt.Errorf("HTTP状态码: %d", resp.StatusCode)
		} else {
			lastErr = err
		}
		
		// JSON API快速重试:只等待很短时间
		if i < maxRetries-1 {
			time.Sleep(100 * time.Millisecond) // 从秒级改为100毫秒
		}
	}
	
	return nil, fmt.Errorf("[%s] 请求失败,重试%d次后仍失败: %w", p.Name(), maxRetries, lastErr)
}

// GetPerformanceStats 获取性能统计信息
func (p *OugeAsyncPlugin) GetPerformanceStats() map[string]interface{} {
	totalRequests := atomic.LoadInt64(&searchRequests)
	totalTime := atomic.LoadInt64(&totalSearchTime)
	
	var avgTime float64
	if totalRequests > 0 {
		avgTime = float64(totalTime) / float64(totalRequests) / 1e6 // 转换为毫秒
	}
	
	return map[string]interface{}{
		"search_requests":    totalRequests,
		"avg_search_time_ms": avgTime,
		"total_search_time_ns": totalTime,
	}
}

View on GitHub (pinned to beaa561337)