{"record":{"id":"072657f759892f90","repo":"ZhuLinsen/daily_stock_analysis","slug":"futu-openapi-sdk-exc","errorCode":null,"errorMessage":"加载 Futu OpenAPI SDK 失败: {exc}","messagePattern":"加载 Futu OpenAPI SDK 失败: (.+?)","errorType":"exception","errorClass":"FutuPortfolioError","httpStatus":null,"severity":"error","filePath":"src/brokers/futu/portfolio.py","lineNumber":72,"sourceCode":"\n    try:\n        from futu import (\n            Market,\n            OpenQuoteContext,\n            OpenSecTradeContext,\n            RET_OK,\n            SecurityFirm,\n            SecurityType,\n            TrdEnv,\n            TrdMarket,\n        )\n    except ImportError as exc:\n        raise FutuPortfolioError(\n            \"未安装 Futu OpenAPI SDK；请先执行 \"\n            \"`pip install \\\"futu-api==10.8.6808\\\"`。\"\n        ) from exc\n    except Exception as exc:  # noqa: BLE001 - SDK import initializes its file logger\n        raise FutuPortfolioError(f\"加载 Futu OpenAPI SDK 失败: {exc}\") from exc\n\n    return _FutuApi(\n        OpenQuoteContext=OpenQuoteContext,\n        OpenSecTradeContext=OpenSecTradeContext,\n        Market=Market,\n        RET_OK=RET_OK,\n        SecurityFirm=SecurityFirm,\n        SecurityType=SecurityType,\n        TrdEnv=TrdEnv,\n        TrdMarket=TrdMarket,\n    )\n\n\ndef _enum_text(value: Any) -> str:\n    \"\"\"Normalize SDK enum-like values for stable comparisons.\"\"\"\n\n    if value is None:\n        return \"\"","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/ZhuLinsen/daily_stock_analysis/blob/5159bd72e8373d215492dff122acc9d389e219c9/src/brokers/futu/portfolio.py#L54-L90","documentation":"FutuPortfolioError raised at src/brokers/futu/portfolio.py:72 when the 'import futu' call fails with something other than ImportError — most commonly an exception thrown during the SDK's module-level initialization (the comment notes it initializes a file logger at import time). The original exception text is embedded so the root cause stays visible.","triggerScenarios":"Importing futu in an environment where its import-time logger setup fails: unwritable futu log directory (it writes under the CWD/futu-api path), permission-restricted container filesystem, locale/encoding problems, or a broken/partially-installed package whose submodule import raises RuntimeError/OSError.","commonSituations":"Running the app as a user without write permission to the directory where futu-api creates its logs; read-only Docker containers; half-completed pip installs; version mismatch where a transitive dependency of futu-api fails to import.","solutions":["Reproduce the import standalone: python -c \"import futu\" — the traceback shows the underlying failure (logger path, permissions, missing transitive dep).","Run the process from a writable working directory or grant write access to the futu log location so import-time logger initialization succeeds.","Reinstall the SDK cleanly at the pinned version: pip install --force-reinstall \"futu-api==10.8.6808\" to repair a partially installed package.","If a transitive dependency is the cause, install/upgrade that dependency per the traceback."],"exampleFix":"# before: app crashes inside broker init with wrapped error\n\n# after: pre-flight check with writable cwd\nimport os, subprocess, sys\nos.makedirs(\"/tmp/futu-workdir\", exist_ok=True)\nos.chdir(\"/tmp/futu-workdir\")\ntry:\n    import futu  # noqa: F401\nexcept Exception as exc:\n    print(f\"futu import failed: {exc}\", file=sys.stderr)\n    sys.exit(1)","handlingStrategy":"try-catch","validationCode":"import os, tempfile\n\ndef futu_import_precheck() -> None:\n    \"\"\"futu-api initializes a file logger at import; ensure cwd is writable.\"\"\"\n    if not os.access(os.getcwd(), os.W_OK):\n        os.chdir(tempfile.mkdtemp())\n    import futu  # noqa: F401  (raises with real cause if broken)","typeGuard":null,"tryCatchPattern":"try:\n        import futu  # noqa: F401\n    except Exception as exc:  # not just ImportError: init-time failures\n        print(f'futu import failed: {exc!r}')\n        raise","preventionTips":["Run the process from a writable directory so futu's import-time logger can initialize.","Verify installs with 'python -c \"import futu\"' before starting the app.","Avoid partial installs: use pip install --force-reinstall when repairing futu-api."],"tags":["futu","import","environment","permissions"],"backgroundTag":null,"analyzedSha":"5159bd72e8373d215492dff122acc9d389e219c9","analyzedAt":"2026-08-15T01:59:36.292Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}