jackwener/OpenCLI · info · EmptyResultError

1point3acres thread

Error message

1point3acres thread

What it means

EmptyResultError thrown when the fetched thread page contains neither the `postlist` container nor any `post_<pid>` divs — i.e. the HTML returned does not look like a real thread page. The library treats this as 'the thread does not exist or was deleted' rather than attempting to parse garbage HTML.

Solutions

  1. Verify the tid is correct by opening the thread URL in a browser
  2. Try page 1 to confirm the thread itself exists
  3. Check whether the thread requires login/permissions the fetch (guest) session lacks
  4. If the page renders in a browser but the CLI fails, the HTML structure check may be outdated — update the marker regex

Example fix

// before
thread({ tid: '2856313', page: 50 })  // EmptyResultError on out-of-range page
// after
thread({ tid: '2856313', page: 1 })
Defensive patterns

Strategy: try-catch

Validate before calling

if (!/^\d+$/.test(String(tid ?? '').trim())) throw new Error('tid must be numeric');

Type guard

null

Try / catch

try {
  const posts = await thread({ tid, page });
} catch (e) {
  if (e instanceof EmptyResultError) {
    // treat as thread-missing: skip or notify
  } else throw e;
}

Prevention

When it happens

Trigger: Requesting `thread-<tid>-<page>-1.html` where the tid is invalid, the thread was deleted/moderated, or a page number beyond the last page was requested and the site returns an error/notice page instead of post markup.

Common situations: Threads removed by moderators (common on the forum); typos in the tid; requesting page 99 of a 3-page thread; login-walled threads where the guest view is an error notice.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/133fdbe3c878b024. Report an issue: GitHub.

Appendix: source

Thrown at clis/1point3acres/thread.js:46

        { name: 'limit', type: 'int', default: 10, help: '返回楼层条数(默认 10,含主楼)' },
        { name: 'contentLimit', type: 'int', default: 400, help: '每楼正文截断长度(默认 400 字符,最少 50)' },
    ],
    columns: ['floor', 'pid', 'author', 'postTime', 'content', 'url'],
    func: async (args) => {
        const tid = String(args.tid || '').trim();
        if (!/^\d+$/.test(tid)) {
            throw new ArgumentError('tid must be a numeric thread id');
        }
        const page = normalizePositiveInteger(args.page, 1, 'page');
        const limit = normalizePositiveInteger(args.limit, 10, 'limit');
        const contentLimit = normalizePositiveInteger(args.contentLimit, 400, 'contentLimit', { min: 50 });

        const url = `${BASE}/thread-${tid}-${page}-1.html`;
        const html = await fetchHtml(url);

        // Sanity: real thread page will contain postlist + at least one post div.
        if (!/id="postlist"/.test(html) && !/id="post_\d+"/.test(html)) {
            throw new EmptyResultError('1point3acres thread', `帖子 ${tid} 不存在或被删除`);
        }

        // Split posts: each post block is bounded by <div id="post_<PID>">…</div> next post or postlist end.
        // NOTE: intermediate objects intentionally use postId/body/offset (not pid/html/start) to
        // avoid being mistaken for row-shaped objects by the silent-column-drop audit.
        const postBlocks = [];
        const re = /<div id="post_(\d+)"[^>]*>/g;
        const offsets = [];
        let m;
        while ((m = re.exec(html))) offsets.push({ postId: m[1], offset: m.index });
        for (let i = 0; i < offsets.length; i++) {
            const segStart = offsets[i].offset;
            const segEnd = i + 1 < offsets.length ? offsets[i + 1].offset : html.length;
            postBlocks.push({ postId: offsets[i].postId, body: html.slice(segStart, segEnd) });
        }

        const rows = [];
        for (let i = 0; i < postBlocks.length && rows.length < limit; i++) {

View on GitHub (pinned to 49907e53dc)