{"record":{"id":"4b6414d679cfa301","repo":"jackwener/OpenCLI","slug":"jike-search-api-failed-string-body-message","errorCode":null,"errorMessage":"Jike search API failed: ${String(body?.message || 'malformed response')}","messagePattern":"Jike search API failed: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/jike/search.js","lineNumber":18,"sourceCode":"import { ArgumentError, CommandExecutionError, EmptyResultError } from '@jackwener/opencli/errors';\nimport { cli, Strategy } from '@jackwener/opencli/registry';\nimport { normalizeJikeLimit, postJikeApi, requireJikeIdentity } from './utils.js';\n\nconst API_PATH = '/1.0/search/integrate';\nconst PAGE_SIZE = 20;\nconst DEFAULT_LIMIT = 20;\nconst MAX_PAGES = 50;\n\nasync function fetchSearchPage(page, keyword, loadMoreKey) {\n    const requestBody = {\n        keywords: keyword,\n        limit: PAGE_SIZE,\n        ...(loadMoreKey ? { loadMoreKey } : {}),\n    };\n    const body = await postJikeApi(page, API_PATH, requestBody, 'Jike search API');\n    if (!body || typeof body !== 'object' || body.success !== true || !Array.isArray(body.data)) {\n        throw new CommandExecutionError(`Jike search API failed: ${String(body?.message || 'malformed response')}`);\n    }\n    return body;\n}\n\nfunction mapPost(post) {\n    if (!post || typeof post !== 'object' || typeof post.id !== 'string' || !post.id) {\n        throw new CommandExecutionError('Jike search API returned a malformed post');\n    }\n    const content = typeof post.content === 'string' ? post.content : '';\n    return {\n        id: post.id,\n        author: typeof post.user?.screenName === 'string' ? post.user.screenName : '',\n        content: content.replace(/\\n/g, ' ').slice(0, 120),\n        likes: Number.isFinite(Number(post.likeCount)) ? Number(post.likeCount) : 0,\n        comments: Number.isFinite(Number(post.commentCount)) ? Number(post.commentCount) : 0,\n        time: typeof post.actionTime === 'string' ? post.actionTime : (typeof post.createdAt === 'string' ? post.createdAt : ''),\n        url: `https://web.okjike.com/originalPost/${post.id}`,\n    };","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/jike/search.js#L1-L36","documentation":"fetchSearchPage posts to the Jike search API and requires a body that is an object with success === true and a `data` array. Any other response is wrapped in CommandExecutionError, including the server-provided message when present.","triggerScenarios":"The Jike search endpoint returns success !== true, a missing/non-array data field, an HTML error page, or a rate-limit/auth-failure payload instead of the expected envelope.","commonSituations":"Jike search rate limiting (search endpoints are often stricter); expired session token; special characters in the keyword breaking the request; Jike API outage; envelope change in a new API version.","solutions":["Re-authenticate / refresh the Jike session token","Read the embedded message in the error to distinguish rate limit vs auth vs server error","Retry with backoff after a rate limit","Simplify/escape the search keyword and verify it returns results in the Jike app"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// basic pre-flight checks before searching\nif (!process.env.JIKE_TOKEN) throw new Error('JIKE_TOKEN not set');\nif (!keyword || !keyword.trim()) throw new Error('keyword required');","typeGuard":"function isSearchBody(b) {\n  return b !== null && typeof b === 'object' && b.success === true && Array.isArray(b.data);\n}","tryCatchPattern":"try {\n  await cli('jike', 'search', [keyword]).run();\n} catch (e) {\n  if (String(e.message).startsWith('Jike search API failed:')) {\n    await sleep(3000); // search rate limits are strict; backoff then retry\n  } else throw e;\n}","preventionTips":["Throttle search calls — Jike rate limits search aggressively","Refresh session tokens before batch searches","Keep the CLI updated for Jike API envelope changes"],"tags":["network","api-response","search","jike"],"backgroundTag":"api-error-response","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}