jackwener/OpenCLI · error · CommandExecutionError
${label} failed: ${detail}
Error message
${label} failed: ${detail} What it means
If the JSON request inside fetchNowcoderData throws for any reason that is NOT an auth failure (no 401/403 or login-related message), the library wraps the underlying error as CommandExecutionError with the label prefix and the original detail, e.g. 'Nowcoder posts list failed: net::ERR_CONNECTION_TIMED_OUT'. It preserves the root cause text so you can diagnose the real transport problem.
Source
Thrown at clis/nowcoder/posts.js:249
export function requirePositiveInt(value, name, maximum) {
const number = Number(value);
if (!Number.isInteger(number) || number < 1 || number > maximum) throw new ArgumentError(`nowcoder --${name} must be an integer from 1 to ${maximum}`);
return number;
}
export async function fetchNowcoderData(page, url, options, label) {
let payload;
try {
await page.goto('https://www.nowcoder.com');
payload = await page.fetchJson(url, options);
}
catch (error) {
const detail = String(error?.message ?? error);
if (/HTTP\s+(401|403)|need login|not logged in/i.test(detail)) {
throw new AuthRequiredError('nowcoder.com', `${label} requires a logged-in Nowcoder session`);
}
throw new CommandExecutionError(`${label} failed: ${detail}`);
}
if (!isRecord(payload) || typeof payload.success !== 'boolean' || !Number.isSafeInteger(payload.code)) throw new CommandExecutionError(`${label} returned a malformed envelope`);
const message = typeof payload.msg === 'string' ? payload.msg : 'unknown error';
if (!payload.success || payload.code !== 0) {
if (payload.code === 999 || /need login|登录/i.test(message)) {
throw new AuthRequiredError('nowcoder.com', `${label} requires a logged-in Nowcoder session: ${message}`);
}
throw new CommandExecutionError(`${label} failed: ${message} (${payload.code})`);
}
if (!isRecord(payload.data)) throw new CommandExecutionError(`${label} returned malformed data`);
return payload.data;
}
View on GitHub (pinned to 49907e53dc)
Solutions
- Read the detail suffix for the root cause (timeout, DNS, HTTP status) and address that specifically.
- Retry after a delay — transient network or rate-limit issues usually clear up.
- Check general connectivity to www.nowcoder.com (curl or browser) to distinguish local network issues from server issues.
- If rate-limited, slow down request frequency or add delays between calls.
- Verify proxy/VPN/firewall settings if the failure is persistent for nowcoder.com only.
Example fix
// before
for (const id of ids) await getPost(id); // rapid loop -> rate limited
// after
for (const id of ids) { await getPost(id); await sleep(2000); } Defensive patterns
Strategy: retry
Validate before calling
// pre-flight connectivity check
const ok = await fetch('https://www.nowcoder.com', { method: 'HEAD' }).then(r => r.ok).catch(() => false);
if (!ok) throw new Error('nowcoder.com unreachable; fix network/proxy before running'); Try / catch
async function withRetry(fn, attempts = 3) {
for (let i = 0; i < attempts; i++) {
try { return await fn(); }
catch (err) {
if (err instanceof AuthRequiredError || i === attempts - 1) throw err;
await new Promise(r => setTimeout(r, 2000 * 2 ** i));
}
}
}
// withRetry(() => nowcoderPostsList(opts)); Prevention
- Add exponential backoff and jitter around all nowcoder fetches.
- Throttle request rate to avoid rate limits and anti-bot responses.
- Check proxy/VPN/firewall settings when failures are persistent.
- Parse the 'failed: <detail>' suffix to route timeouts, DNS, and 5xx differently.
When it happens
Trigger: Network timeouts, DNS failures, connection resets, TLS errors, HTTP 5xx, 404s, rate limiting (429), or anti-bot HTML responses during page.goto or page.fetchJson for a nowcoder data command.
Common situations: Nowcoder being slow or down; corporate proxy/firewall blocking the request; being rate-limited after rapid successive calls; transient offline network; antivirus/SSL interception breaking TLS.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- Bilibili creator comparison request failed: ${detail}
- arXiv API HTTP ${resp.status}
- coingecko categories returned HTTP ${resp.status}
- ${label} returned HTTP ${resp.status}
- Flomo API returned HTTP ${resp.status}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/738fe5e83bdc29b2.
Report an issue: GitHub.