{"record":{"id":"cb16bce0b9bd10d2","repo":"jackwener/OpenCLI","slug":"nowcoder-source","errorCode":null,"errorMessage":"nowcoder ${source}","messagePattern":"nowcoder (.+?)","errorType":"exception","errorClass":"EmptyResultError","httpStatus":null,"severity":"warning","filePath":"clis/nowcoder/posts.js","lineNumber":173,"sourceCode":"        return {\n            ...commonFeedFields(data, post, 'moment', post.userId, post.createdAt, index),\n            id: uuid,\n            uuid,\n            entity_id: entityId,\n            url: `https://www.nowcoder.com/feed/main/detail/${uuid}`,\n        };\n    }\n    throw new CommandExecutionError(`Nowcoder returned unsupported feed contentType ${String(data.contentType)}`);\n}\n\nexport function projectNowcoderFeed(records, limit, source, wrapped = false) {\n    if (!Array.isArray(records)) throw new CommandExecutionError(`Nowcoder ${source} returned malformed records`);\n    const rows = [];\n    for (const record of records) {\n        const data = wrapped ? record?.data : record;\n        rows.push(projectFeedData(data, rows.length, source === 'experience' || wrapped));\n    }\n    if (rows.length === 0) throw new EmptyResultError(`nowcoder ${source}`, 'Nowcoder returned no content or moment posts.');\n    return rows.slice(0, limit);\n}\n\nexport function parseNowcoderPostTarget(raw) {\n    const value = typeof raw === 'string' ? raw.trim() : '';\n    if (NUMERIC_ID_PATTERN.test(value)) return { post_type: 'content', value };\n    if (UUID_PATTERN.test(value)) return { post_type: 'moment', value: value.toLowerCase() };\n\n    let url;\n    try {\n        url = new URL(value);\n    }\n    catch {\n        throw new ArgumentError('nowcoder detail requires a numeric content ID, moment UUID, or canonical Nowcoder URL');\n    }\n    const host = url.hostname.toLowerCase();\n    if (url.protocol !== 'https:' || url.username || url.password || url.port || url.hash\n        || (host !== 'nowcoder.com' && host !== 'www.nowcoder.com')) {","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/nowcoder/posts.js#L155-L191","documentation":"After projecting all rows, projectNowcoderFeed throws EmptyResultError when zero posts survived, using `nowcoder ${source}` as the scope and the message 'Nowcoder returned no content or moment posts.' This distinguishes 'the feed worked but is empty' from malformed-data errors, letting callers handle emptiness (e.g., print 'no posts' or try another source) distinctly from hard failures.","triggerScenarios":"Calling projectNowcoderFeed with an empty records array, or a records array whose every element was filtered out / had an unsupported or malformed shape you pre-filtered, with a valid limit.","commonSituations":"A user's feed genuinely has no posts (new account, restrictive filters, wrong --limit range upstream); querying the 'experience' source for a user with no shared experiences; pagination walked past the last page; an over-aggressive pre-filter removed all rows.","solutions":["Catch EmptyResultError and treat it as a normal empty state rather than a failure.","Try another feed source (e.g., 'recommend' instead of 'experience') or broaden query filters.","Check that your pre-filtering did not remove every row before projection.","Verify pagination parameters — request page 1 or fewer items if you walked past the end."],"exampleFix":"// before\nconst rows = projectNowcoderFeed(records, 10, 'experience');\n// after\nlet rows;\ntry {\n    rows = projectNowcoderFeed(records, 10, 'experience');\n} catch (error) {\n    if (error instanceof EmptyResultError) rows = [];\n    else throw error;\n}","handlingStrategy":"try-catch","validationCode":"if (Array.isArray(records) && records.length === 0) {\n    // handle empty feed up front instead of calling projection\n    return [];\n}","typeGuard":null,"tryCatchPattern":"import { EmptyResultError } from '@jackwener/opencli/errors';\ntry {\n    rows = projectNowcoderFeed(records, limit, source, wrapped);\n} catch (error) {\n    if (error instanceof EmptyResultError) {\n        rows = []; // normal empty state, not a failure\n    } else throw error;\n}","preventionTips":["Treat EmptyResultError as an expected empty state and catch it separately","Try another feed source or broaden filters when a feed is empty","Check pagination — you may have walked past the last page","Ensure pre-filters are not removing every row before projection"],"tags":["empty-result","feed-parsing","expected-condition"],"backgroundTag":"empty-result-set","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}