{"record":{"id":"32e2fa9072543a14","repo":"decolua/9router","slug":"http-res-status","errorCode":null,"errorMessage":"`HTTP ${res.status}`","messagePattern":"`HTTP (.+?)`","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"src/shared/components/ChangelogModal.js","lineNumber":23,"sourceCode":"import PropTypes from \"prop-types\";\nimport { marked } from \"marked\";\nimport { GITHUB_CONFIG } from \"@/shared/constants/config\";\n\nmarked.setOptions({ gfm: true, breaks: true });\n\nexport default function ChangelogModal({ isOpen, onClose }) {\n  const [html, setHtml] = useState(\"\");\n  const [loading, setLoading] = useState(false);\n  const [error, setError] = useState(\"\");\n  const modalRef = useRef(null);\n\n  useEffect(() => {\n    if (!isOpen || html) return;\n    setLoading(true);\n    setError(\"\");\n    fetch(GITHUB_CONFIG.changelogUrl)\n      .then((res) => {\n        if (!res.ok) throw new Error(`HTTP ${res.status}`);\n        return res.text();\n      })\n      .then((md) => setHtml(marked.parse(md)))\n      .catch((err) => setError(err.message || \"Failed to load\"))\n      .finally(() => setLoading(false));\n  }, [isOpen, html]);\n\n  useEffect(() => {\n    const handleClickOutside = (e) => {\n      if (modalRef.current && !modalRef.current.contains(e.target)) {\n        onClose();\n      }\n    };\n    if (isOpen) {\n      document.addEventListener(\"mousedown\", handleClickOutside);\n      return () => document.removeEventListener(\"mousedown\", handleClickOutside);\n    }\n  }, [isOpen, onClose]);","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/decolua/9router/blob/90b52e06ffd666b7929554211474d01588f6b1f8/src/shared/components/ChangelogModal.js#L5-L41","documentation":"ChangelogModal fetches markdown from GITHUB_CONFIG.changelogUrl and throws `HTTP ${res.status}` whenever the response is not ok (non-2xx). The thrown message is caught in the same effect and shown as the modal's error text. It is a thin HTTP-status passthrough, so the message is literally like 'HTTP 404' or 'HTTP 403'.","triggerScenarios":"fetch(GITHUB_CONFIG.changelogUrl) resolving with res.ok === false — e.g. 404 when CHANGELOG.md does not exist at that path/branch in the repo, 403 from GitHub rate limiting, 5xx from GitHub, or a network-level redirect to an error page.","commonSituations":"Repo renamed/branch renamed so the raw changelog URL 404s; GitHub API/raw rate limit (403) after many requests; offline or corporate proxy blocking raw.githubusercontent.com; misconfigured GITHUB_CONFIG owner/repo values.","solutions":["Check GITHUB_CONFIG.changelogUrl points to an existing file (open it in a browser); fix owner/repo/branch/path if it 404s","If 403, wait out the GitHub rate limit or use an authenticated/raw URL with caching","Verify network access to the host (curl the URL); configure proxy if blocked","Render a fallback: link the user to the changelog page on GitHub when fetch fails"],"exampleFix":"// before\nif (!res.ok) throw new Error(`HTTP ${res.status}`);\n// after\nif (!res.ok) throw new Error(`Changelog load failed (HTTP ${res.status}). Check ${GITHUB_CONFIG.changelogUrl}`);","handlingStrategy":"try-catch","validationCode":"const res = await fetch(GITHUB_CONFIG.changelogUrl, { method: \"HEAD\" });\nif (!res.ok) console.warn(\"Changelog unavailable:\", res.status);","typeGuard":"function isOk(res) { return res && typeof res.ok === \"boolean\" && res.ok; }","tryCatchPattern":"try {\n  const res = await fetch(GITHUB_CONFIG.changelogUrl);\n  if (!res.ok) throw new Error(`HTTP ${res.status}`);\n  setHtml(marked.parse(await res.text()));\n} catch (err) {\n  setError(err.message || \"Failed to load\");\n  // show fallback link to the changelog on GitHub\n}","preventionTips":["Pin changelogUrl to a stable tag/commit, not a moving branch","Add retry with backoff for transient GitHub 5xx/403 rate limits","Cache the last successfully loaded changelog for offline display","Keep GITHUB_CONFIG owner/repo in sync with repo renames"],"tags":["http","fetch","github","ui"],"backgroundTag":"http-request-failed","analyzedSha":"90b52e06ffd666b7929554211474d01588f6b1f8","analyzedAt":"2026-08-30T21:05:45.952Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}