{"record":{"id":"3834a171be0ee25e","repo":"fish2018/pansou","slug":"s-suggest-host-s-code-d-msg-s","errorCode":null,"errorMessage":"[%s] suggest 响应异常: host=%s code=%d msg=%s","messagePattern":"\\[(.+?)\\] suggest 响应异常: host=(.+?) code=(.+?) msg=(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/qiwei/qiwei.go","lineNumber":214,"sourceCode":"\t\tif err := p.solveVerification(client, searchURL, body); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"[%s] 搜索验证失败: %w\", p.Name(), err)\n\t\t}\n\t\tbody, err = p.fetchBody(client, searchURL, host+\"/\", searchTimeout)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif isVerifyPage(body) {\n\t\t\treturn nil, fmt.Errorf(\"[%s] 命中验证页: %s\", p.Name(), host)\n\t\t}\n\t}\n\n\tvar resp suggestResponse\n\tif err := json.Unmarshal([]byte(body), &resp); err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] suggest 响应解析失败: %w\", p.Name(), err)\n\t}\n\n\tif resp.Code != 1 && len(resp.List) == 0 {\n\t\treturn nil, fmt.Errorf(\"[%s] suggest 响应异常: host=%s code=%d msg=%s\", p.Name(), host, resp.Code, resp.Msg)\n\t}\n\n\treturn resp.List, nil\n}\n\nfunc (p *QiweiPlugin) enrichResults(client *http.Client, host string, items []suggestItem, forceRefresh bool) []model.SearchResult {\n\tresults := make([]model.SearchResult, len(items))\n\tvar wg sync.WaitGroup\n\tsem := make(chan struct{}, maxConcurrent)\n\n\tfor i, item := range items {\n\t\twg.Add(1)\n\t\tgo func(idx int, it suggestItem) {\n\t\t\tdefer wg.Done()\n\t\t\tsem <- struct{}{}\n\t\t\tdefer func() { <-sem }()\n\n\t\t\tresults[idx] = p.buildResult(client, host, it, forceRefresh)","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/qiwei/qiwei.go#L196-L232","documentation":"Raised in searchSuggest (plugin/qiwei/qiwei.go:214) when the suggest JSON parses but indicates an abnormal result: resp.Code != 1 AND resp.List is empty. The body is valid JSON from the site's API, but it reports a business-level failure (its own error code and msg) rather than a normal result. This treats a legitimately empty search as OK (empty list with code 1 passes) while failing on explicit API errors.","triggerScenarios":"The endpoint returns JSON like {\"code\":0,\"msg\":\"...\",\"list\":[]} — non-1 code with zero items. Fired by the check `if resp.Code != 1 && len(resp.List) == 0` after successful unmarshal.","commonSituations":"Upstream API degraded or returning its own error codes (maintenance, DB issues); anti-bot returning JSON-form errors; extremely rare keyword edge cases triggering server-side errors; the site changed its success code convention from 1 to something else.","solutions":["Read host/code/msg embedded in the error — a consistent upstream msg means site-side trouble; wait or rely on other mirrors.","If the site changed its success convention (e.g. code 200), update the `resp.Code != 1` check in qiwei.go to match the new contract.","Confirm with curl that a known-good keyword returns code 1; if yes, the failure is keyword-specific, not environmental.","Treat as transient: searchSuggestWithFallback will try remaining hosts, and pansou merges results from other plugins."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// pre-check parsed response before treating it as an error\nif resp.Code == 1 || len(resp.List) > 0 {\n    return resp.List, nil // healthy response\n}\n// otherwise it's the abnormal-code path; retry next host","typeGuard":null,"tryCatchPattern":"items, err := p.searchSuggest(client, host, keyword)\nif err != nil && strings.Contains(err.Error(), \"suggest 响应异常\") {\n    log.Printf(\"qiwei upstream API error on %s: %v; trying next host\", host, err)\n    continue\n}","preventionTips":["Track whether upstream error codes become persistent — that signals an API contract change needing a code update (resp.Code != 1 check)","Verify expected success shape with curl for a known keyword before assuming site outage","Prefer graceful degradation: let searchSuggestWithFallback exhaust mirrors and merge results from other plugins"],"tags":["api","upstream","unexpected-response","scraping"],"backgroundTag":"unexpected-api-response-shape","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"}