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

  1. Check network connectivity and retry loading the popup later, since the error is usually transient on ccfddl.com's side.
  2. Open https://ccfddl.com/conference/deadlines_en.ics directly in a browser to confirm the endpoint is healthy and returns 200.
  3. Check whether a proxy, VPN, or firewall is intercepting requests and returning non-200 responses; whitelist ccfddl.com.
  4. 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

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)