{"record":{"id":"ea2daaaf2342f4a5","repo":"BigPizzaV3/CodexPlusPlus","slug":"app","errorCode":null,"errorMessage":"创建失败","messagePattern":"创建失败","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"services/share-site/app.js","lineNumber":46,"sourceCode":"\n  form.addEventListener(\"submit\", async (event) => {\n    event.preventDefault();\n    setNotice(\"\");\n    submit.disabled = true;\n    submit.textContent = \"正在加密...\";\n\n    try {\n      const encrypted = await encryptText(content.value);\n      const response = await fetch(\"/api/shares\", {\n        method: \"POST\",\n        headers: { \"Content-Type\": \"application/json\" },\n        body: JSON.stringify({\n          encrypted: encrypted.payload,\n          ttl: Number(document.querySelector(\"#ttl\").value),\n        }),\n      });\n      const data = await response.json();\n      if (!response.ok) throw new Error(data.error || \"创建失败\");\n\n      const url = new URL(location.origin);\n      url.searchParams.set(\"s\", data.id);\n      url.hash = `k=${encrypted.key}`;\n      shareUrl.value = url.toString();\n      localStorage.setItem(`codexpp-share-delete:${data.id}`, data.deleteToken);\n      result.dataset.shareId = data.id;\n      result.hidden = false;\n      setNotice(\"链接已创建。正文和密钥均未以明文发送。\", \"success\");\n    } catch (error) {\n      setNotice(error instanceof Error ? error.message : \"创建失败，请稍后重试。\", \"error\");\n    } finally {\n      submit.disabled = false;\n      submit.textContent = \"加密并创建链接\";\n    }\n  });\n\n  document.querySelector(\"[data-copy]\").addEventListener(\"click\", async () => {","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6/services/share-site/app.js#L28-L64","documentation":"Thrown by the share-site's setupComposer after POSTing the encrypted payload to the share creation API. When the HTTP response is not ok, the server-provided data.error is used as the message; otherwise the generic \"创建失败\" (\"creation failed\") is thrown. The share URL and delete token are only stored after this check passes.","triggerScenarios":"Submitting the share composer form when the API returns 4xx/5xx (invalid payload, ttl out of range, payload too large, server error), or a 2xx body without the expected id/fields that still trips response.ok checks via data.error being absent.","commonSituations":"Share service backend is down or misconfigured; ttl value invalid (e.g. empty or non-numeric input in #ttl after Number() coercion yields NaN); encrypted payload exceeds server body limit; server rejects request due to rate limits or missing CSRF/auth headers.","solutions":["Check the Network tab for the failing request's status and response body — the data.error field contains the server's reason.","Verify the ttl input (#ttl) holds a valid positive number; Number(\"\") is 0 and Number of garbage is NaN, both likely rejected server-side.","Confirm the payload size is within the server's body limit; re-encrypt or trim the shared content if 413.","Retry later for 5xx errors, and check the share service's health/logs server-side."],"exampleFix":"// before: NaN/0 ttl submitted silently\nttl: Number(document.querySelector(\"#ttl\").value),\n// after: validate ttl before submitting\nconst ttl = Number(document.querySelector(\"#ttl\").value);\nif (!Number.isInteger(ttl) || ttl <= 0) {\n  alert(\"请输入有效的 TTL（正整数秒）\");\n  return;\n}\n// ... body: JSON.stringify({ encrypted: encrypted.payload, ttl })","handlingStrategy":"validation","validationCode":"const ttl = Number(document.querySelector(\"#ttl\").value);\nif (!Number.isFinite(ttl) || ttl <= 0) throw new Error(\"请输入有效的 TTL\");\nif (!encrypted?.payload) throw new Error(\"缺少加密数据\");","typeGuard":"function isShareResponse(v) {\n  return v != null && typeof v === \"object\" && typeof v.id === \"string\" && typeof v.deleteToken === \"string\";\n}","tryCatchPattern":"try {\n  const response = await fetch(\"/api/shares\", { method: \"POST\", body: JSON.stringify(payload) });\n  const data = await response.json().catch(() => ({}));\n  if (!response.ok || !isShareResponse(data)) {\n    throw new Error(data.error || `创建失败（HTTP ${response.status}）`);\n  }\n} catch (e) {\n  statusEl.textContent = e.message;\n}","preventionTips":["Validate ttl and encrypted payload client-side before submitting.","Show the server's data.error verbatim to help users diagnose 4xx causes.","Disable the submit button while the request is in flight to avoid duplicate/aborted requests.","Monitor share API uptime and surface a clear 'service unavailable' state for 5xx."],"tags":["http","share","network","validation"],"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"}