{"record":{"id":"8ecdf9e484814bf3","repo":"fish2018/pansou","slug":"s-hsid-s-d","errorCode":null,"errorMessage":"[%s] hsid=%s链接请求返回状态码: %d","messagePattern":"\\[(.+?)\\] hsid=(.+?)链接请求返回状态码: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/haisou/haisou.go","lineNumber":409,"sourceCode":"\t}\n\n\t// 设置请求头\n\treq.Header.Set(\"User-Agent\", \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36\")\n\treq.Header.Set(\"Accept\", \"application/json, text/plain, */*\")\n\treq.Header.Set(\"Accept-Language\", \"zh-CN,zh;q=0.9,en;q=0.8\")\n\treq.Header.Set(\"Connection\", \"keep-alive\")\n\treq.Header.Set(\"Referer\", \"https://haisou.cc/\")\n\n\t// 发送HTTP请求（带重试机制）\n\tresp, err := p.doRequestWithRetry(req, client)\n\tif err != nil {\n\t\treturn \"\", \"\", fmt.Errorf(\"[%s] hsid=%s链接请求失败: %w\", p.Name(), hsid, err)\n\t}\n\tdefer resp.Body.Close()\n\n\t// 检查状态码\n\tif resp.StatusCode != 200 {\n\t\treturn \"\", \"\", fmt.Errorf(\"[%s] hsid=%s链接请求返回状态码: %d\", p.Name(), hsid, resp.StatusCode)\n\t}\n\n\t// 读取响应体\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn \"\", \"\", fmt.Errorf(\"[%s] hsid=%s读取响应失败: %w\", p.Name(), hsid, err)\n\t}\n\n\t// 解析响应\n\tvar apiResp FetchAPIResponse\n\tif err := json.Unmarshal(body, &apiResp); err != nil {\n\t\treturn \"\", \"\", fmt.Errorf(\"[%s] hsid=%s链接JSON解析失败: %w\", p.Name(), hsid, err)\n\t}\n\n\t// 检查API响应状态\n\tif apiResp.Code != 0 {\n\t\treturn \"\", \"\", fmt.Errorf(\"[%s] hsid=%s链接API错误: %s\", p.Name(), hsid, apiResp.Msg)\n\t}","sourceCodeStart":391,"sourceCodeEnd":427,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/haisou/haisou.go#L391-L427","documentation":"This error is thrown when the share-link HTTP response status code is anything other than 200. The plugin treats only HTTP 200 as success; upstream errors (4xx/5xx) like 403 anti-bot, 429 rate limit, or 502 upstream failure are reported here with the raw status code. Note the response body is not included, so the reason must be inferred.","triggerScenarios":"fetchShareLink gets a response whose StatusCode != 200 after doRequestWithRetry succeeded at the transport level.","commonSituations":"haisou.cc anti-bot/WAF returns 403 for flagged UAs or IPs; rate limiting returns 429; upstream CDN returns 502/503 during outages; API path changed returning 404.","solutions":["Log the response body on non-200 to capture the upstream reason (read and truncate body before returning)","Retry with backoff on 429/5xx statuses; treat 4xx as non-retryable","Rotate User-Agent or route through a proxy if 403 persists","Verify the fetch URL/path is still valid after API changes (404)","Consider honoring Retry-After header on 429/503 responses."],"exampleFix":"// before\nif resp.StatusCode != 200 {\n\treturn \"\", \"\", fmt.Errorf(\"[%s] hsid=%s链接请求返回状态码: %d\", p.Name(), hsid, resp.StatusCode)\n}\n// after\nif resp.StatusCode != 200 {\n\tsnippet, _ := io.ReadAll(io.LimitReader(resp.Body, 200))\n\treturn \"\", \"\", fmt.Errorf(\"[%s] hsid=%s链接请求返回状态码: %d (body=%s)\", p.Name(), hsid, resp.StatusCode, string(snippet))\n}","handlingStrategy":"retry","validationCode":"// status can only be checked after the call; guard by retrying on retryable codes\nif resp.StatusCode == 429 || resp.StatusCode >= 500 {\n\t// retry with backoff, honor Retry-After\n}","typeGuard":null,"tryCatchPattern":"if resp.StatusCode != http.StatusOK {\n\tbody, _ := io.ReadAll(io.LimitReader(resp.Body, 512))\n\treturn fmt.Errorf(\"unexpected status %d: %s\", resp.StatusCode, body)\n}","preventionTips":["Log response bodies on non-200 to capture WAF/captcha pages","Back off on 429/5xx; never hammer the upstream","Rotate User-Agent/IP if 403 anti-bot responses persist","Track upstream API path changes to avoid 404s"],"tags":["http","status-code","upstream","go"],"backgroundTag":"http-non-200-response","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"}