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

  1. Check basic connectivity: curl -I https://www.guazi.com/ (or the underlying err.message for the exact cause)
  2. Configure HTTPS_PROXY/HTTP_PROXY env vars if a proxy is required
  3. Retry the command — transient connection resets are common with scraped sites
  4. 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

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


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