{"record":{"id":"03f1e0a89d4b900e","repo":"BigPizzaV3/CodexPlusPlus","slug":"app-03f1e0","errorCode":null,"errorMessage":"分享不存在、已撤销或已过期。","messagePattern":"分享不存在、已撤销或已过期。","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"services/share-site/app.js","lineNumber":100,"sourceCode":"    setNotice(\"分享已撤销。\", \"success\");\n  });\n}\n\nasync function showShare(id) {\n  createView.hidden = true;\n  viewer.hidden = false;\n  const viewContent = document.querySelector(\"[data-view-content]\");\n  const viewMeta = document.querySelector(\"[data-view-meta]\");\n  const viewNotice = document.querySelector(\"[data-view-notice]\");\n  const importButton = document.querySelector(\"[data-import-session]\");\n\n  try {\n    const keyValue = new URLSearchParams(location.hash.slice(1)).get(\"k\");\n    if (!keyValue) throw new Error(\"链接缺少解密密钥。请使用完整的分享链接。\");\n\n    const response = await fetch(`/api/shares/${id}`, { cache: \"no-store\" });\n    const data = await response.json();\n    if (!response.ok) throw new Error(\"分享不存在、已撤销或已过期。\");\n\n    const plaintext = await decryptText(data.encrypted, keyValue);\n    try {\n      const parsed = JSON.parse(plaintext);\n      if (parsed?.kind === \"codex-rollout\" && typeof parsed.content === \"string\") {\n        sharedSession = parsed;\n        viewContent.textContent = rolloutToMarkdown(parsed.content, parsed.title);\n        importButton.hidden = false;\n        importButton.addEventListener(\"click\", importSharedSession, { once: true });\n      } else if (parsed?.kind === \"codex-session\" && Array.isArray(parsed.messages)) {\n        sharedSession = parsed;\n        viewContent.textContent = sessionToMarkdown(parsed);\n        importButton.hidden = false;\n        importButton.addEventListener(\"click\", importSharedSession, { once: true });\n      } else {\n        viewContent.textContent = plaintext;\n      }\n    } catch {","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6/services/share-site/app.js#L82-L118","documentation":"After fetching /api/shares/:id, showShare() checks response.ok; any non-2xx (404, 410, etc.) is converted into this single user-facing error. The server rejects the share because it does not exist, was revoked by its owner, or has passed its expiry time, and the client collapses all these cases into one message for privacy (not revealing which).","triggerScenarios":"Calling showShare with an id whose share record returns 404/410 from GET /api/shares/:id, with cache:\"no-store\" so a fresh authoritative response is always required.","commonSituations":"Opening a link after the share expired (TTL elapsed), after the author revoked it, with a mistyped/truncated id, or against the wrong backend/deployment where the share was never created.","solutions":["Confirm the URL id segment matches the original share link exactly (no truncation by copy/paste).","Request a fresh share link from the author — if it expired or was revoked only a new link will work.","Check you are on the same site/deployment the share was created on; shares are not cross-host.","If you are the operator, inspect the /api/shares/:id handler logs to distinguish 404 vs 410 vs 403."],"exampleFix":"// before\nif (!response.ok) throw new Error(\"分享不存在、已撤销或已过期。\");\n// after\nif (response.status === 410) throw new Error(\"该分享已过期，请向分享者索取新链接。\");\nif (!response.ok) throw new Error(\"分享不存在、已撤销或已过期。\");","handlingStrategy":"try-catch","validationCode":"const res = await fetch(`/api/shares/${id}`, { cache: \"no-store\" });\nif (res.status === 404 || res.status === 410) {\n  viewNotice.textContent = \"该分享已失效，请索取新的分享链接。\";\n  return;\n}","typeGuard":null,"tryCatchPattern":"try {\n  await showShare(id);\n} catch (e) {\n  if (e.message === \"分享不存在、已撤销或已过期。\") {\n    viewNotice.textContent = \"分享链接已失效或已过期，请联系分享者重新生成。\";\n  } else { throw e; }\n}","preventionTips":["Open share links soon after receiving them; assume they have a TTL.","Keep the original message with the link so you can request a fresh one when it expires.","Verify the id segment of the URL is not truncated when copy/pasting.","Check you are on the same host the share was created on."],"tags":["http","rest","resource-not-found","fetch"],"backgroundTag":"http-error-response","analyzedSha":"b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6","analyzedAt":"2026-09-19T23:35:21.129Z","contentChangedAt":"2026-09-19T23:35:21.129Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}