{"record":{"id":"4bf3cd704e7c115c","repo":"jackwener/OpenCLI","slug":"weread-search-no-books-were-returned-for-query","errorCode":null,"errorMessage":"weread search: No books were returned for query ${args.query}.","messagePattern":"weread search: No books were returned for query (.+?)\\.","errorType":"exception","errorClass":"EmptyResultError","httpStatus":null,"severity":"warning","filePath":"clis/weread/search.js","lineNumber":155,"sourceCode":"    domain: 'weread.qq.com',\n    strategy: Strategy.PUBLIC,\n    browser: false,\n    args: [\n        { name: 'query', positional: true, required: true, help: 'Search keyword' },\n        { name: 'limit', type: 'int', default: 10, help: 'Max results' },\n    ],\n    columns: ['rank', 'title', 'author', 'bookId', 'url'],\n    func: async (args) => {\n        const [data, htmlEntries] = await Promise.all([\n            fetchWebApi('/search/global', { keyword: args.query }),\n            loadSearchHtmlEntries(String(args.query ?? '')),\n        ]);\n        const books = data?.books ?? [];\n        if (!Array.isArray(books)) {\n            throw new CommandExecutionError('WeRead search API returned an unreadable books payload');\n        }\n        if (books.length === 0) {\n            throw new EmptyResultError('weread search', `No books were returned for query ${args.query}.`);\n        }\n        const { exactQueues, titleOnlyQueues } = buildSearchUrlQueues(htmlEntries);\n        const apiIdentityCounts = countSearchIdentities(books.map((item) => ({\n            title: item.bookInfo?.title ?? '',\n            author: item.bookInfo?.author ?? '',\n        })));\n        const htmlIdentityCounts = countSearchIdentities(htmlEntries.filter((entry) => entry.author));\n        const apiTitleCounts = countSearchTitles(books.map((item) => ({ title: item.bookInfo?.title ?? '' })));\n        const htmlTitleCounts = countSearchTitles(htmlEntries);\n        return books.slice(0, Number(args.limit)).map((item, i) => {\n            const title = item.bookInfo?.title ?? '';\n            const author = item.bookInfo?.author ?? '';\n            return {\n                rank: i + 1,\n                title,\n                author,\n                bookId: item.bookInfo?.bookId ?? '',\n                url: resolveSearchResultUrl({","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/weread/search.js#L137-L173","documentation":"An EmptyResultError thrown by the `weread search` command when both the public API and the scraped HTML page yield zero books for the query. This is a deliberate, expected signal that the search legitimately found nothing — not a malfunction. It carries the command name ('weread search') and the query so callers can distinguish it from real failures.","triggerScenarios":"GET /web/search/books and /search/global both return empty results for `args.query` — e.g. a misspelled title, an overly specific keyword, a query of rare/obscure content not in WeRead's catalog, or queries with only whitespace after coercion via String(args.query ?? '').","commonSituations":"Typo or wrong-language query (searching English title when only the Chinese edition exists); quoting/punctuation in the query that over-constrains matching; testing the CLI with random strings; a book that was removed from the WeRead catalog.","solutions":["Shorten the query to a distinctive keyword (author surname or 2–4 core title words) and retry.","Search in the language of the catalog edition (Chinese titles for WeRead content).","Strip punctuation/quotes from the query; try the ISBN or alternate title.","Treat EmptyResultError as a control-flow signal in scripts: catch it and report 'no results' instead of a generic failure.","Confirm in a browser at https://weread.qq.com/web/search that the book exists at all."],"exampleFix":"// before\nweread search \"The Three Body Problem Book I Hard cover edition\"\n// after\nweread search \"三体\"","handlingStrategy":"try-catch","validationCode":"// Check the query is non-trivial before invoking the command\nconst q = query.trim();\nif (q.length < 2) throw new Error('Query too short — likely to return zero results');","typeGuard":null,"tryCatchPattern":"import { EmptyResultError } from '@jackwener/opencli/errors';\ntry {\n  const rows = await runWereadSearch(query);\n} catch (e) {\n  if (e instanceof EmptyResultError) {\n    console.log(`No WeRead books match \"${query}\" — try a shorter or Chinese-language keyword`);\n    return [];\n  }\n  throw e;\n}","preventionTips":["Treat EmptyResultError as expected control flow, not a crash","Sanitize queries: trim, strip punctuation, keep 2–6 distinctive keywords","Prefer catalog-language (Chinese) titles when searching WeRead","Verify a book exists on weread.qq.com in a browser before scripting around it"],"tags":["empty-result","search","weread","no-results"],"backgroundTag":"empty-search-results","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}