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.

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)

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.