ccfddl/ccf-deadlines · error · Error
加载失败
Error message
加载失败
What it means
This error is thrown by the popup's deadline loader when neither of the two ICS feeds from ccfddl.com (deadlines_zh.ics and deadlines_en.ics) returned an HTTP OK response; after filtering with res.ok, the responses array is empty and Error('加载失败') is raised. It means the remote conference-deadline data could not be fetched, so the popup cannot render any CCF deadlines.
Solutions
- Check network connectivity and retry loading the popup later, since the error is usually transient on ccfddl.com's side.
- Open https://ccfddl.com/conference/deadlines_en.ics directly in a browser to confirm the endpoint is healthy and returns 200.
- Check whether a proxy, VPN, or firewall is intercepting requests and returning non-200 responses; whitelist ccfddl.com.
- Patch popup.js to surface res.status in the error message and fall back to cached deadlines instead of failing outright.
Example fix
// before
const responses = [zhResponse, enResponse].filter((res) => res.ok);
if (responses.length === 0) throw new Error("加载失败");
// after
const responses = [zhResponse, enResponse].filter((res) => res.ok);
if (responses.length === 0) {
throw new Error(`加载失败 (zh=${zhResponse.status}, en=${enResponse.status})`);
} Defensive patterns
Strategy: try-catch
Validate before calling
const res = await fetch(url, { method: "HEAD" }).catch(() => null);
if (!res || !res.ok) console.warn("ccfddl feed unavailable, status:", res?.status); Type guard
function hasOkResponses(responses) {
return Array.isArray(responses) && responses.some((res) => res && res.ok);
} Try / catch
try {
await loadCcfddlDeadlines();
} catch (err) {
if (err.message === "加载失败") {
showCachedDeadlinesOrMessage("无法加载会议截止时间,请稍后重试");
} else {
throw err;
}
} Prevention
- Cache the last successful ICS parse in chrome.storage and render it when fetches fail.
- Retry the fetch once or twice with backoff before giving up.
- Log response statuses (res.status) to distinguish 4xx/5xx from network outages.
- Show a retry button in the popup instead of a dead '加载失败' state.
When it happens
Trigger: Both fetch() calls to https://ccfddl.com/conference/deadlines_zh.ics and https://ccfddl.com/conference/deadlines_en.ics resolve with res.ok === false (e.g. HTTP 4xx/5xx), or the site is down; if either fetch rejects (network error/DNS failure/CORS), Promise.all rejects instead and this specific message is not thrown.
Common situations: User is offline or behind a captive portal/proxy that returns non-200 responses; ccfddl.com is temporarily down, rate-limiting, or returning 403/503 via CDN; corporate firewall blocks the domain; the site changed URL structure so the endpoints return 404.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
AI-assisted analysis of ccfddl/ccf-deadlines@dedf5e76ab (2026-09-11).
Data as JSON: /api/errors/b21e2d8884236c9a.
Report an issue: GitHub.
Appendix: source
Thrown at extensions/chrome/chrome/popup.js:637
const repoResponse = await fetch(
"https://ccfddl.github.io/conference/allconf.yml"
);
if (repoResponse.ok) {
const repoText = await repoResponse.text();
const now = Date.now();
const parsedItems = mergeCcfddlItems(parseAllConfYaml(repoText))
.filter((item) => toTimestamp(item.datetime) >= now)
.sort((a, b) => toTimestamp(a.datetime) - toTimestamp(b.datetime));
applyLoadedCcfddlItems(parsedItems);
return;
}
const [zhResponse, enResponse] = await Promise.all([
fetch("https://ccfddl.com/conference/deadlines_zh.ics"),
fetch("https://ccfddl.com/conference/deadlines_en.ics"),
]);
const responses = [zhResponse, enResponse].filter((res) => res.ok);
if (responses.length === 0) throw new Error("加载失败");
const texts = await Promise.all(responses.map((res) => res.text()));
const now = Date.now();
const parsedItems = mergeCcfddlItems(texts.flatMap((text) => parseIcs(text)))
.filter((item) => toTimestamp(item.datetime) >= now)
.sort((a, b) => toTimestamp(a.datetime) - toTimestamp(b.datetime));
applyLoadedCcfddlItems(parsedItems);
} catch (error) {
if (ccfddlItems.length === 0) {
ccfddlEmpty.textContent = t("load_failed", "加载失败,请稍后重试。");
ccfddlEmpty.style.display = isCcfddlExpanded && isCcfddlDropdownOpen ? "block" : "none";
}
} finally {
isCcfddlLoading = false;
}
}
async function openCcfddlDropdown() {
if (!isCcfddlExpanded) return;View on GitHub (pinned to dedf5e76ab)