{"record":{"id":"0def0d9812d8737a","repo":"fish2018/pansou","slug":"s-api-w-0def0d","errorCode":null,"errorMessage":"[%s] API 搜索请求失败: %w","messagePattern":"\\[(.+?)\\] API 搜索请求失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/dyyj/dyyj.go","lineNumber":423,"sourceCode":"\tparams.Set(\"filter[q]\", keyword)\n\tparams.Set(\"include\", \"mostRelevantPost\")\n\tparams.Set(\"page[limit]\", fmt.Sprintf(\"%d\", MaxResults))\n\tapiURL := BaseURL + \"/api/discussions?\" + params.Encode()\n\n\tctx, cancel := context.WithTimeout(context.Background(), RequestTimeout)\n\tdefer cancel()\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, apiURL, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 创建 API 请求失败: %w\", p.Name(), err)\n\t}\n\treq.Header.Set(\"User-Agent\", UserAgent)\n\treq.Header.Set(\"Accept\", \"application/vnd.api+json, application/json\")\n\treq.Header.Set(\"Accept-Language\", \"zh-CN,zh;q=0.9,en;q=0.8\")\n\treq.Header.Set(\"Referer\", BaseURL+\"/\")\n\n\tresp, err := p.doRequestWithRetry(req, client)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] API 搜索请求失败: %w\", p.Name(), err)\n\t}\n\tdefer resp.Body.Close()\n\n\tvar payload dyyjAPIResponse\n\tif err := encodingjson.NewDecoder(resp.Body).Decode(&payload); err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 解析 API 响应失败: %w\", p.Name(), err)\n\t}\n\n\tposts := make(map[string]dyyjIncluded, len(payload.Included))\n\tfor _, post := range payload.Included {\n\t\tposts[post.ID] = post\n\t}\n\n\tresults := make([]model.SearchResult, 0, len(payload.Data))\n\tfor _, discussion := range payload.Data {\n\t\tpost, ok := posts[discussion.Relationships.MostRelevantPost.Data.ID]\n\t\tif !ok {\n\t\t\tcontinue","sourceCodeStart":405,"sourceCodeEnd":441,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/dyyj/dyyj.go#L405-L441","documentation":"The Flarum API request in dyyj.executeSearchAPI failed at the transport level after doRequestWithRetry exhausted retries. Wraps DNS/TCP/TLS errors and context deadline exceeded. Retries have already occurred; this is the terminal failure.","triggerScenarios":"p.doRequestWithRetry(req, client) errored on GET {BaseURL}/api/discussions?... — DNS failure, connection refused/reset, TLS error, or RequestTimeout exceeded.","commonSituations":"API host unreachable from the deployment network; site blocked datacenter IPs; API endpoint removed (connection-level symptom less common — usually 404, but domain loss gives DNS errors); proxy required but unset.","solutions":["curl -v the same apiURL from the host to classify the failure","Check DNS resolution of the BaseURL host","Configure proxy environment variables if egress requires one","Increase RequestTimeout for slow API responses","Check whether the site moved/renamed its domain"],"exampleFix":"// before\nresp, err := p.doRequestWithRetry(req, client)\nif err != nil {\n\treturn nil, fmt.Errorf(\"[%s] API 搜索请求失败: %w\", p.Name(), err)\n}\n// after\nresp, err := p.doRequestWithRetry(req, client)\nif err != nil {\n\tif errors.Is(err, context.DeadlineExceeded) {\n\t\treturn nil, fmt.Errorf(\"[%s] API 搜索超时(>%s): %w\", p.Name(), RequestTimeout, err)\n\t}\n\treturn nil, fmt.Errorf(\"[%s] API 搜索请求失败: %w\", p.Name(), err)\n}","handlingStrategy":"retry","validationCode":"conn, err := net.DialTimeout(\"tcp\", host+\":443\", 3*time.Second)\nif err != nil { return errors.New(\"API host unreachable\") }; conn.Close()","typeGuard":null,"tryCatchPattern":"resp, err := p.doRequestWithRetry(req, client)\nif err != nil {\n\tvar netErr net.Error\n\tif errors.As(err, &netErr) && netErr.Timeout() {\n\t\treturn nil, fmt.Errorf(\"API timeout: %w\", err)\n\t}\n\treturn nil, fmt.Errorf(\"API transport error: %w\", err)\n}","preventionTips":["Keep bounded retries with exponential backoff for transient failures","Set explicit client and context timeouts","Verify egress/proxy access to the API host in deployment","Alert on sustained DNS/connect failures for the target domain"],"tags":["network","http","api","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"}