{"record":{"id":"c231f21c451d7f24","repo":"BigPizzaV3/CodexPlusPlus","slug":"error-c231f2","errorCode":null,"errorMessage":"未连接","messagePattern":"未连接","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/codex-plus-mobile-relay/src/main.rs","lineNumber":858,"sourceCode":"        return;\n      }\n      if (response.type === \"appServerClosed\") {\n        appServerConnected = false;\n        for (const item of pendingRpc.values()) item.reject(new Error(response.error || \"app-server 连接已关闭\"));\n        pendingRpc.clear();\n        setStatus(response.error || \"app-server 连接已关闭\", !!response.error);\n        return;\n      }\n      const id = String(response.id ?? \"\");\n      const resolver = pending.get(id);\n      if (resolver) { pending.delete(id); resolver.resolve(response); return; }\n    } catch (error) {\n      setStatus(`解密/解析失败：${error.message}`, true);\n    }\n  };\n}\nasync function request(path, body = \"\", timeoutMs = 30000) {\n  if (!socket || socket.readyState !== WebSocket.OPEN) throw new Error(\"未连接\");\n  const id = `${Date.now()}-${requestId++}`;\n  const packet = await encrypt({ type: \"httpRequest\", id, method: body ? \"POST\" : \"GET\", path, headers: {}, body });\n  socket.send(JSON.stringify(packet));\n  return await new Promise((resolve, reject) => {\n    pending.set(id, { resolve, reject });\n    setTimeout(() => { if (pending.delete(id)) reject(new Error(\"请求超时\")); }, timeoutMs);\n  });\n}\nasync function ensureAppServer() {\n  if (appServerConnected && appServerSessionId) return;\n  appServerSessionId = appServerSessionId || `mobile-${Date.now()}-${Math.random().toString(16).slice(2)}`;\n  const id = `${Date.now()}-${requestId++}`;\n  const packet = await encrypt({ type: \"appServerConnect\", id, sessionId: appServerSessionId });\n  socket.send(JSON.stringify(packet));\n  await new Promise((resolve, reject) => {\n    pending.set(id, { resolve, reject });\n    setTimeout(() => { if (pending.delete(id)) reject(new Error(\"app-server 连接超时\")); }, 30000);\n  });","sourceCodeStart":840,"sourceCodeEnd":876,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/f2074595a281bc057525c748175c8eb9805b0673/apps/codex-plus-mobile-relay/src/main.rs#L840-L876","documentation":"Client error in mobile_relay_page ('not connected'): an RPC was attempted while the relay has no live app-server session/connection, so the request cannot be routed. Fired when the app-server link dropped or was never established before the call.","triggerScenarios":"Thrown at apps/codex-plus-mobile-relay/src/main.rs:858 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Reconnect / call ensureAppServer to re-establish the session","Check the relay's app-server child process is running","Retry after the WebSocket reconnects"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"f2074595a281bc057525c748175c8eb9805b0673","analyzedAt":"2026-08-23T12:52:24.489Z","contentChangedAt":"2026-08-23T12:52:24.489Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}