{"record":{"id":"7acb3be8c7159d42","repo":"jackwener/OpenCLI","slug":"sina-blog-search-failed-http-resp-status","errorCode":null,"errorMessage":"Sina blog search failed: HTTP ${resp.status}","messagePattern":"Sina blog search failed: HTTP (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"clis/sinablog/search.js","lineNumber":23,"sourceCode":"function stripHtml(value) {\n    return value.replace(/<[^>]+>/g, '');\n}\nasync function searchSinaBlog(keyword, limit) {\n    const url = new URL('https://search.sina.com.cn/api/search');\n    url.searchParams.set('q', keyword);\n    url.searchParams.set('tp', 'mix');\n    url.searchParams.set('sort', '0');\n    url.searchParams.set('page', '1');\n    url.searchParams.set('size', String(Math.max(limit, 10)));\n    url.searchParams.set('from', 'search_result');\n    const resp = await fetch(url, {\n        headers: {\n            'User-Agent': 'Mozilla/5.0',\n            Accept: 'application/json',\n        },\n    });\n    if (!resp.ok)\n        throw new Error(`Sina blog search failed: HTTP ${resp.status}`);\n    const data = await resp.json();\n    const list = Array.isArray(data?.data?.list) ? data.data.list : [];\n    return list\n        .filter((item) => normalize(item?.url).includes('blog.sina.com.cn/s/blog_'))\n        .slice(0, limit)\n        .map((item, index) => ({\n        rank: index + 1,\n        title: normalize(stripHtml(item?.title || '')),\n        author: normalize(item?.media_show || item?.author),\n        date: normalize(item?.time || item?.dataTime),\n        description: normalize(item?.intro || item?.searchSummary).slice(0, 150),\n        url: normalize(item?.url),\n    }));\n}\ncli({\n    site: 'sinablog',\n    name: 'search',\n    access: 'read',","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/sinablog/search.js#L5-L41","documentation":"searchSinaBlog in clis/sinablog/search.js queries Sina's public search API (search.sina.com.cn/api/search) and throws a plain Error when resp.ok is false, embedding the HTTP status. There is no retry or key handling — any non-2xx (403 anti-bot, 429 throttle, 5xx outage) surfaces as this error.","triggerScenarios":"fetch to https://search.sina.com.cn/api/search?q=... returns a non-ok status: Sina's WAF blocking the default 'Mozilla/5.0' UA with 403, rate limiting with 429, or backend 5xx during outages.","commonSituations":"Running from datacenter IPs Sina blocks; heavy scripted searches tripping rate limits; Sina search API deprecations/changes returning error statuses; regional network restrictions.","solutions":["Retry after a delay — 429/5xx are often transient.","Use a realistic browser User-Agent and route through a residential/network path not blocked by Sina.","Check whether the search API endpoint/params changed and update the URL or params.","Reduce request frequency and add backoff between searches.","Fall back to another Sina search surface or a cached index if the API is down."],"exampleFix":"// before\nif (!resp.ok) throw new Error(`Sina blog search failed: HTTP ${resp.status}`);\n// after: retry once with backoff on 429/5xx\nlet resp = await fetch(url, { headers });\nif (resp.status === 429 || resp.status >= 500) {\n  await new Promise(r => setTimeout(r, 2000));\n  resp = await fetch(url, { headers });\n}\nif (!resp.ok) throw new Error(`Sina blog search failed: HTTP ${resp.status}`);","handlingStrategy":"retry","validationCode":"const keywordOk = typeof keyword === 'string' && keyword.trim().length > 0;\nconst limitOk = Number.isInteger(limit) && limit >= 1 && limit <= 50;\nif (!keywordOk || !limitOk) throw new Error('Invalid search keyword or limit');","typeGuard":null,"tryCatchPattern":"try {\n  const results = await searchSinaBlog(keyword, limit);\n} catch (err) {\n  const m = /HTTP (\\d{3})/.exec(err.message);\n  if (m && (+m[1] === 429 || +m[1] >= 500)) {\n    await new Promise(r => setTimeout(r, 2000));\n    return searchSinaBlog(keyword, limit); // one retry\n  }\n  if (m && +m[1] === 403) console.error('Blocked by Sina; use a browser-like UA or different network');\n  throw err;\n}","preventionTips":["Throttle request rate; Sina search is easily rate-limited.","Use a realistic browser User-Agent to reduce WAF 403s.","Add backoff retries for 429/5xx.","Have a fallback data source for when the search API is down.","Avoid datacenter IPs that Sina commonly blocks."],"tags":["http","network","scraping","sina"],"backgroundTag":"http-non-ok-status","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}