jackwener/OpenCLI · error · CommandExecutionError
guazi ${contextHint} network error: ${err?.message || err}
Error message
guazi ${contextHint} network error: ${err?.message || err} What it means
guaziFetch wraps its fetch of a Guazi mobile page in try/catch and rethrows any network-level failure (DNS, TLS, timeout, connection refused, abort) as a CommandExecutionError with the contextHint and underlying message. It exists so scraping commands fail with a typed, descriptive error instead of an opaque fetch exception.
Source
Thrown at clis/guazi/utils.js:117
export function requireStableId(value, label) {
const id = String(value ?? '').trim();
if (!/^\d+$/.test(id)) throw new CommandExecutionError(`${label} did not include a stable numeric id.`);
return id;
}
/** Fetch a Guazi mobile page as HTML text, throwing typed errors. */
export async function guaziFetch(path, contextHint) {
let resp;
try {
resp = await fetch(`${GUAZI_M_BASE}${path}`, {
headers: {
'User-Agent': UA,
Referer: `${GUAZI_M_BASE}/`,
'Accept-Language': 'zh-CN,zh;q=0.9',
},
});
} catch (err) {
throw new CommandExecutionError(`guazi ${contextHint} network error: ${err?.message || err}`);
}
if (!resp.ok) {
throw new CommandExecutionError(`guazi ${contextHint} HTTP ${resp.status}`);
}
const html = await resp.text();
// Guazi may eventually push the mobile pages behind their JS challenge.
if (/瑞数|reese84|captcha|滑动验证|verify\.guazi|安全验证/i.test(html) && !/car-detail\/c\d+/.test(html)) {
throw new AuthRequiredError(
'guazi.com',
`guazi ${contextHint} hit an anti-bot challenge — Guazi may have started gating the mobile site.`,
);
}
return html;
}
export { ArgumentError, CommandExecutionError, EmptyResultError };
View on GitHub (pinned to 49907e53dc)
Solutions
- Check basic connectivity: curl -I https://www.guazi.com/ (or the underlying err.message for the exact cause)
- Configure HTTPS_PROXY/HTTP_PROXY env vars if a proxy is required
- Retry the command — transient connection resets are common with scraped sites
- Inspect err?.message embedded in the error text to identify DNS vs TLS vs timeout
Example fix
// before
await guaziFetch('/car/123', 'car page'); // offline
// CommandExecutionError: guazi car page network error: fetch failed
// after
if (!navigator.onLine) throw new Error('go online first');
await guaziFetch('/car/123', 'car page'); Defensive patterns
Strategy: retry
Validate before calling
// check connectivity before calling
const ok = await fetch('https://guazi.com/', { method: 'HEAD' }).then(() => true).catch(() => false);
if (!ok) throw new Error('no network access to guazi.com'); Type guard
const isNetworkError = (e) => e instanceof CommandExecutionError && /network error/.test(e.message);
Try / catch
try {
const html = await guaziFetch(path, hint);
} catch (e) {
if (isNetworkError(e) && isRetryable(e)) return retryWithBackoff(() => guaziFetch(path, hint), 3);
throw e;
} Prevention
- Configure proxy env vars (HTTPS_PROXY) when behind a corporate network
- Implement exponential backoff retries around guaziFetch
- Fail fast with a connectivity check before long scrape runs
- Log the embedded cause (err?.message) for diagnosis
When it happens
Trigger: Calling guaziFetch(path, contextHint) when the network request to GUAZI_M_BASE throws: no internet, DNS resolution failure for guazi.com, TLS errors, request timeouts/aborts, or proxy failures. Non-2xx responses do NOT hit this path (see HTTP error).
Common situations: Running the CLI offline or behind a restrictive corporate proxy; DNS/ad-blocker blocking guazi.com; Node fetch TLS certificate issues; transient connection resets from the Guazi mobile site.
Related errors
- 1point3acres request failed: ${error?.message || error}
- 1point3acres request failed: HTTP ${res.status} ${res.status
- FETCH_ERROR
- archive search request failed: ${error?.message || error}
- archive wayback request failed: ${error?.message || error}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/7d7afd6f3b0fca7e.
Report an issue: GitHub.