maboloshi/github-chinese · error · Error
HTTP ${res.status} ${url}
Error message
HTTP ${res.status} ${url} What it means
fetchText() is the VS Code extension's helper that pulls the translation bundle (LOCALS_URL) and the main script (MAIN_URL) from the NJU mirror over globalThis.fetch at extension-activate time, bypassing page CSP. On any non-2xx response it throws HTTP <status> <url>. refreshSource() catches this and returns null, which leaves _source null and makes the status bar show '词库 ❌ 加载失败'; the error message appears in the extension host log.
Source
Thrown at vscode-extension/src/extension.ts:98
let _statusBar: vscode.StatusBarItem;
const _tabs = new Map<BrowserTabLike, TabEntry>();
let _source: string | null = null;
// ─── browser API 检测 ────────────────────────────────────────
function isBrowserApiAvailable(): boolean {
const w = vscode.window as any;
return typeof w.browserTabs !== 'undefined'
&& typeof w.onDidOpenBrowserTab === 'function'
&& typeof w.onDidCloseBrowserTab === 'function';
}
// ─── 注入源码构建 ─────────────────────────────────────────────
async function fetchText(url: string): Promise<string> {
const res = await (globalThis as any).fetch(url);
if (!res.ok) { throw new Error(`HTTP ${res.status} ${url}`); }
return res.text();
}
/**
* 构建注入源码:GM_* 兼容层 + 等 DOM 就绪后执行词库与主脚本(document-end 语义)。
* 通过 CDP Page.addScriptToEvaluateOnNewDocument 直接注入(不 eval),
* 规避 github.com CSP 对 eval 的限制(IBE 因用 new Function 被 CSP 拦截)。
*/
async function refreshSource(): Promise<string | null> {
try {
const [locals, main] = await Promise.all([fetchText(LOCALS_URL), fetchText(MAIN_URL)]);
_source = `(function () {
'use strict';
/* ---- GM_* 兼容层(无 IBE 时补齐页面端 GM API)---- */
var gm = {
addStyle: function (css) {
var el = document.createElement('style');
el.textContent = css;View on GitHub (pinned to 1db777260a)
Solutions
- Check VS Code's proxy: set 'http.proxy' and 'http.proxyStrictSSL' appropriately, then reload the window so refreshSource re-fetches.
- Open https://mirror.nju.edu.cn/github-chinese/locals.js and .../main.user.js in a browser to confirm the mirror is up and the paths still resolve.
- If the NJU mirror is persistently unreachable, change LOCALS_URL/MAIN_URL in extension.ts to a reachable mirror (e.g. raw.githubusercontent gh-pages) and rebuild the extension.
- Run the extension's refresh command again once network is restored; injection is guarded on _source truthiness so it self-heals on a successful re-fetch.
Example fix
// before
async function fetchText(url: string): Promise<string> {
const res = await (globalThis as any).fetch(url);
if (!res.ok) { throw new Error(`HTTP ${res.status} ${url}`); }
return res.text();
}
// after — retry transient 5xx/network errors with backoff
async function fetchText(url: string, tries = 3): Promise<string> {
let last: Error | null = null;
for (let i = 0; i < tries; i++) {
try {
const res = await (globalThis as any).fetch(url);
if (res.ok) return res.text();
last = new Error(`HTTP ${res.status} ${url}`);
if (res.status < 500) throw last; // 4xx won't fix themselves
} catch (e) { last = e as Error; }
await new Promise(r => setTimeout(r, 500 * (i + 1)));
}
throw last ?? new Error(`fetch failed ${url}`);
} Defensive patterns
Strategy: retry
Validate before calling
// Before activation relies on the mirror, confirm reachability:
async function mirrorReachable(url: string): Promise<boolean> {
try {
const r = await (globalThis as any).fetch(url, { method: 'HEAD' });
return r.ok;
} catch {
return false;
}
}
// usage: if (!(await mirrorReachable(LOCALS_URL))) { showProxyHint(); } Type guard
null
Try / catch
let src: string | null = null;
try {
src = await refreshSource();
} catch (e) {
console.error('[github-chinese] source refresh failed:', e);
src = null;
}
if (!src) {
vscode.window.showWarningMessage('GitHub 汉化资源拉取失败,请检查网络/代理/镜像');
return;
} Prevention
- Configure VS Code http.proxy (and http.proxyStrictSSL) in firewalled environments.
- Guard every injection on _source truthiness — the code already does this at the inject site.
- Add a fallback mirror URL and prefer whichever resolves first.
- Pre-fetch resources on cold start and cache _source so a transient outage doesn't disable translation.
When it happens
Trigger: At activation (or when the refresh command runs) one of the two mirror URLs returns non-ok: a 404 if the mirror path changed, a 5xx while the mirror is down, or fetch throws (DNS/TLS/proxy/timeout) which surfaces as a rejected promise inside refreshSource's try. The thrown HTTP string is what the catch logs.
Common situations: Running VS Code behind a corporate proxy without http.proxy configured; the NJU mirror being down or rate-limiting; offline/cold start with no cached _source; a mirror path rename; a self-hosted environment that cannot reach mirror.nju.edu.cn.
Related errors
AI-assisted analysis of maboloshi/github-chinese@1db777260a (2026-08-13).
Data as JSON: /api/errors/868e777d027dd5e9.
Report an issue: GitHub.