{"record":{"id":"fa68581bc06f2c15","repo":"jackwener/OpenCLI","slug":"xiaohongshu-search-failed-err-message-strin","errorCode":null,"errorMessage":"Xiaohongshu search failed: ${err?.message ?? String(err)}","messagePattern":"Xiaohongshu search failed: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/xiaohongshu/search.js","lineNumber":917,"sourceCode":"                }\n            }\n            const rows = harvest.rows\n                .filter((item) => item.title)\n                .slice(0, limit);\n            if (rows.length === 0) {\n                throw new EmptyResultError('xiaohongshu search', 'No usable notes were rendered for this query.');\n            }\n            return rows\n                .map((item, i) => ({\n                rank: i + 1,\n                ...item,\n                published_at: noteIdToDate(item.url),\n            }));\n        }\n        catch (err) {\n            if (err instanceof CliError)\n                throw err;\n            throw new CommandExecutionError(`Xiaohongshu search failed: ${err?.message ?? String(err)}`);\n        }\n    },\n});\nexport const __test__ = {\n    harvestOptionsForLimit,\n    stripXhsAuthorDateSuffix,\n};\n","sourceCodeStart":899,"sourceCodeEnd":925,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/xiaohongshu/search.js#L899-L925","documentation":"A catch-all wrapper at the end of the xiaohongshu search command: any unexpected error that is not already a CliError is rethrown as a CommandExecutionError prefixed with 'Xiaohongshu search failed:'. It preserves the original message but loses the original stack/type, so you must read the embedded message to diagnose.","triggerScenarios":"Any non-CliError exception escapes the try block in the command handler — e.g. navigation failures from page.goto, evaluate timeouts inside collectSearchHarvest, noteIdToDate input errors, or other runtime errors during harvest/processing.","commonSituations":"Navigation timeout because the search page never loaded; browser disconnected mid-harvest; page.evaluate returning undefined and downstream code throwing a TypeError; network outage during the search.","solutions":["Read the embedded message after the prefix — it is the original error's message — and fix that root cause.","Verify network connectivity and that the search URL loads in the logged-in browser.","Increase navigation/operation timeouts if the embedded message indicates a timeout.","Catch this in your caller and retry with backoff for transient navigation failures.","If the embedded message is an opaque TypeError, update the library — it may be a selector/contract change on the site."],"exampleFix":"// before\nconst rows = await xhsSearch(query);\n// after\ntry {\n  const rows = await xhsSearch(query);\n} catch (err) {\n  const cause = String(err.message).replace('Xiaohongshu search failed: ', '');\n  if (/timeout|net::/i.test(cause)) return await retryWithBackoff(() => xhsSearch(query));\n  throw err;\n}","handlingStrategy":"try-catch","validationCode":"if (!browser.isConnected()) throw new Error('browser must be connected before running xiaohongshu search');","typeGuard":"function isCliError(e) { return e instanceof CliError; }","tryCatchPattern":"try {\n  return await xhsSearch(query);\n} catch (err) {\n  if (isCliError(err)) throw err;\n  const cause = err.message.replace(/^Xiaohongshu search failed: /, '');\n  if (/timeout|net::ERR/i.test(cause)) return retryWithBackoff(() => xhsSearch(query));\n  throw err;\n}","preventionTips":["Ensure stable network and reachable XHS before running","Set generous timeouts for navigation","Distinguish CliError subclasses from this wrapper when handling","Log the full embedded cause message"],"tags":["xhs","error-wrapping","command-execution"],"backgroundTag":"wrapped-unknown-error","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}